summaryrefslogtreecommitdiff
path: root/docs
diff options
context:
space:
mode:
Diffstat (limited to 'docs')
-rw-r--r--docs/applications.md24
-rw-r--r--docs/architecture.md15
-rw-r--r--docs/build-steps.md84
-rw-r--r--docs/configuration-logic.md87
-rw-r--r--docs/libproxy.svg1
-rw-r--r--docs/meson.build47
-rw-r--r--docs/perl.md21
-rw-r--r--docs/proxy-authentication.md7
-rw-r--r--docs/px.toml.in71
-rw-r--r--docs/python.md30
-rw-r--r--docs/ruby.md20
-rw-r--r--docs/samples.md4
-rw-r--r--docs/samples/dotnet/Makefile8
-rw-r--r--docs/samples/dotnet/proxy.cs38
-rw-r--r--docs/samples/libcurl/Makefile9
-rw-r--r--docs/samples/libcurl/curlget.c108
-rw-r--r--docs/samples/perl/sample.pl7
-rw-r--r--docs/samples/vala/Makefile7
-rw-r--r--docs/samples/vala/sample.vala9
-rw-r--r--docs/vala.md32
-rw-r--r--docs/version.xml.in1
21 files changed, 630 insertions, 0 deletions
diff --git a/docs/applications.md b/docs/applications.md
new file mode 100644
index 0000000..79fe046
--- /dev/null
+++ b/docs/applications.md
@@ -0,0 +1,24 @@
+Title: Applications - Who is using Libproxy?
+Slug: ApplicationMatrix
+
+# Applications - Who is using Libproxy?
+
+
+| Application | Upstream | Patches |
+| --- | -- | -- |
+| apt | NO | AVAILABLE |
+| cURL | NO | AVAILABLE |
+| eid-viewer | YES | - |
+| glib-networking | YES | - |
+| libQt5Network | YES | - |
+| libzypp | YES | - |
+| Mozilla Firefox | YES | - |
+| neon | YES | - |
+| openconnect | YES | - |
+| python-requests | NO | AVAILABLE |
+| seamonkey | YES | - |
+| signond | YES | - |
+| signond_ui | YES | - |
+| vagalume | YES | - |
+| wget | NO | [Patch](https://build.opensuse.org/package/show/openSUSE:Factory/wget) |
+
diff --git a/docs/architecture.md b/docs/architecture.md
new file mode 100644
index 0000000..35c3596
--- /dev/null
+++ b/docs/architecture.md
@@ -0,0 +1,15 @@
+Title: Architecture - Difference between library and D-Bus service
+Slug: Architecture
+
+
+# Architecture
+
+Starting with release 0.5.0 Libproxy is making use of glib. glib has many
+advantages and helps to get rid of one of the major issues we have had with
+previous versions of Libproxy. To name a few advantages:
+
+- Testing Framework
+- Make use of existing plugin loader
+- Automatic documentation out of code
+- Gobject Introspection bindings for almost every programming language
+
diff --git a/docs/build-steps.md b/docs/build-steps.md
new file mode 100644
index 0000000..2590c4e
--- /dev/null
+++ b/docs/build-steps.md
@@ -0,0 +1,84 @@
+Title: Build steps - How to compile libproxy
+Slug: building
+
+# Build steps - How to compile libproxy
+
+## Fedora
+
+### Dependencies
+
+```
+sudo dnf install glib2-devel duktape-devel libsoup3-devel meson gcovr gi-docgen libcurl-devel vala gsettings-desktop-schemas-devel gobject-introspection-devel
+```
+
+### Build Setup
+
+```
+meson setup build
+```
+
+### Compilation
+
+```
+ninja -C build
+```
+
+### Installation
+
+```
+ninja -C build install
+```
+
+## OS X
+
+### Dependencies
+
+```
+pip install meson ninja
+brew install libsoup icu4c gobject-introspection duktape gcovr gi-docgen curl vala
+```
+
+### Build Setup
+
+```
+meson setup build
+```
+
+### Compilation
+
+```
+ninja -C build
+```
+
+### Installation
+
+```
+ninja -C build install
+```
+
+## Windows (MSYS2)
+
+### Dependencies
+
+```
+pacman -S base-devel git mingw-w64-x86_64-toolchain mingw-w64-x86_64-ccache mingw-w64-x86_64-pkg-config mingw-w64-x86_64-gobject-introspection mingw-w64-x86_64-python-gobject mingw-w64-x86_64-meson mingw-w64-x86_64-glib mingw-w64-x86_64-duktape mingw-w64-x86_64-gi-docgen mingw-w64-x86_64-libsoup3 mingw-w64-x86_64-curl mingw-w64-x86_64-vala
+```
+
+### Build Setup
+
+```
+meson setup build
+```
+
+### Compilation
+
+```
+ninja -C build
+```
+
+### Installation
+
+```
+ninja -C build install
+```
+
diff --git a/docs/configuration-logic.md b/docs/configuration-logic.md
new file mode 100644
index 0000000..783a8db
--- /dev/null
+++ b/docs/configuration-logic.md
@@ -0,0 +1,87 @@
+Title: Configuration Logic
+Slug: Design
+
+# Configuration Logic
+
+## Introduction
+As the proxy configuration predates libproxy, we need to consider previous
+implementation behavior to ensure consistency with user expectations. This page
+presents analyses of well known implementation base on the platform they run on.
+
+## Linux
+On Linux the pioneer of proxy support is Mozilla browsers (former Netscape).
+But other browsers do support proxy and has it's own proxy configuration
+interpretation logic. Current GNOME proxy settings is a copy of Firefox
+settings.
+
+### Firefox
+When using Firefox internal manual settings, the proxy is selected base on the
+most specific proxy (e.g. HTTP before SOCKS). Only one proxy is selected, if
+connection to that proxy fails, then connection fails.
+
+```
+ IF protocol specific proxy is set THEN use it
+ ELSE IF SOCKS proxy is set THEN use it
+ ELSE use direct connection.
+```
+
+### Firefox and Chromium (with GNOME settings)
+After some testing we found that Chromium mimics perfectly Firefox behavior
+when using system settings. When using manual proxy configuration mode, those
+browsers chooses a proxy base on the most generic solution (SOCKS) to the most
+specific (per protocol proxies), with an exception when a single proxy is set
+for all protocols. Only one protocol is selected and no fallback will occur in
+the case of failures. Those browsers support SOCKS, HTTP, HTTPS, FTP and
+Firefox also support Gopher. You can also set the configuration to use a
+specific PAC file or to automatically discover one (WPAD) but those does not
+contain any special logic. Next is the logic represent as pseudo code:
+
+```
+ IF not using same proxy for all protocols THEN
+ IF SOCKS is set THEN use it
+ ELSE IF protocol specific proxy is set THEN use it
+ ELSE IF using same proxy for all protocols THEN
+ IF SOCKS is set THEN use it
+ IF no proxy has been set THEN use direct connection
+```
+
+## OS X
+OS X uses it's own way for proxy settings. It supports protocols including
+SOCKS, HTTP, HTTPS, FTP, Gopher, RTSP, and automatic configuration through PAC
+files. For sake of simplicity, we have tested the logic with the default browser
+Safari.
+
+### Safari
+Safari interpret proxy logic differently from Firefox. If multiple proxy are
+configured, it try each of them until a connection is established. From our
+testing the order seems to be from most specific to most generic (starting with
+manual configuration). Next is the logic represented as pseudo code:
+
+```
+ DEFINE proxy_list as list
+ IF protocol specific proxy is set THEN add it to proxy_list
+ IF SOCKS proxy is set THEN append it to proxy_list
+ IF PAC auto-configuration is set THEN append it to proxy_list
+ FOREACH proxy in proxy_list
+ connect to proxy
+ IF connection failed THEN continue
+ ELSE stop
+```
+
+## Windows
+Windows user most often use Internet Explorer, Firefox or Opera for browsing.
+Analyses as shown that Firefox acts exactly the same as on Linux, except that
+same logic is applied for internal settings and system setting (IE settings).
+Internet explorer also act the same way, and Opera only support protocol
+specific proxies (no SOCKS). So essentially, if chooses choose the most
+specific proxy, and if that one fails the own connection fails.
+
+## Conclusion
+Base on current result, we see that the most common logic is to select a proxy
+starting from the most specific (HTTP, FTP, etc.) to the least specific
+(SOCKS, PAC then WPAD). OS X pushes a bit further by trying all the configure
+proxy that match the protocol. This technique is interesting for libproxy
+since it warranty that connection will be possible for all cases covered by
+the others. The only difference with the GNOME environment is that OS X may
+connect through an HTTP server while Firefox and Chromium (on Gnome) would
+connect to a SOCKS server if both are available.
diff --git a/docs/libproxy.svg b/docs/libproxy.svg
new file mode 100644
index 0000000..70d3793
--- /dev/null
+++ b/docs/libproxy.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16"><g fill="#2a488c"><path d="M4.96 8.635V11H1.367c-.206 0-.368.205-.368.467v1.058c0 .262.162.467.368.467h10.264c.206 0 .368-.205.368-.467v-1.058c0-.262-.162-.467-.368-.467H7.977V8.635z"/><path d="M3.8 0C2.849 0 2 .793 2 1.746v6.613c0 .953.849 1.746 1.868 1.746h5.264c1.02 0 1.868-.793 1.868-1.746V1.746C11 .793 10.151 0 9.132 0zM4 2h5c0 .317 0-.316 0 0v6H4s0 .044 0 0V2c0-.044 0 0 0 0z" style="line-height:normal;-inkscape-font-specification:'Bitstream Vera Sans';text-indent:0;text-align:start;text-decoration-line:none;text-transform:none;marker:none" color="#fff" font-weight="400" font-family="Bitstream Vera Sans" overflow="visible"/><path d="M5 2.971h3v1.003H5zm2 2.005h1v1.002H7z" style="marker:none" color="#fff" overflow="visible"/><path d="M9.229 3c.07 0 0 .209 0 .476v1.078c0 .267.07.476.16.476h4.451c.09 0 .16-.209.16-.476V3.476c0-.267-.07-.476-.16-.476-.16 0-4.585.063-4.611 0zm-3.256 8.624c.08-.06.253.039.394.223l.573.747c.142.184.191.375.112.435l-3.935 2.954c-.08.059-.253-.039-.395-.224l-.573-.746c-.141-.184-.19-.376-.111-.435 0 0 3.946-2.893 3.935-2.954z"/><path d="M7.027 11.624c-.08-.06-.253.039-.394.223l-.573.747c-.142.184-.191.375-.112.435l3.935 2.954c.08.059.253-.039.395-.224l.573-.746c.141-.184.19-.376.111-.435 0 0-3.946-2.893-3.935-2.954z"/></g></svg> \ No newline at end of file
diff --git a/docs/meson.build b/docs/meson.build
new file mode 100644
index 0000000..3c2fae9
--- /dev/null
+++ b/docs/meson.build
@@ -0,0 +1,47 @@
+if get_option('docs')
+
+expand_content_md_files = [
+ 'architecture.md',
+ 'applications.md',
+ 'build-steps.md',
+ 'configuration-logic.md',
+ 'perl.md',
+ 'python.md',
+ 'ruby.md',
+ 'vala.md',
+]
+
+toml_data = configuration_data()
+toml_data.set('VERSION', meson.project_version())
+
+px_toml = configure_file(
+ input: 'px.toml.in',
+ output: 'px.toml',
+ configuration: toml_data
+)
+
+gidocgen = find_program('gi-docgen')
+
+docs_dir = datadir / 'doc'
+
+custom_target('px-doc',
+ input: [ px_toml, libproxy_gir[0] ],
+ output: 'libproxy-@0@'.format(api_version),
+ command: [
+ gidocgen,
+ 'generate',
+ '--quiet',
+ '--add-include-path=@0@'.format(meson.current_source_dir() + '/src'),
+ '--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,
+)
+
+endif
diff --git a/docs/perl.md b/docs/perl.md
new file mode 100644
index 0000000..eee6bbe
--- /dev/null
+++ b/docs/perl.md
@@ -0,0 +1,21 @@
+Title: How to use libproxy in Perl
+Slug: snippets
+
+# How to use libproxy in Perl
+
+```
+#!/usr/bin/perl
+use warnings;
+use Glib::Object::Introspection;
+Glib::Object::Introspection->setup(
+ basename => 'Px',
+ version => '1.0',
+ package => 'Px');
+
+my $pf = new Px::ProxyFactory;
+
+$proxies = $pf->get_proxies("https://github.com/libproxy/libproxy");
+foreach my $proxy (@$proxies) {
+ print $proxy."\n";
+}
+```
diff --git a/docs/proxy-authentication.md b/docs/proxy-authentication.md
new file mode 100644
index 0000000..de7a905
--- /dev/null
+++ b/docs/proxy-authentication.md
@@ -0,0 +1,7 @@
+Title: Proxy Authentication
+Slug: ProxyAuthentication
+
+
+# Proxy Authentication
+Because proxy authentication is protocol specific, it is outside the scope of this library. libproxy tells you WHICH proxy servers to try to use,
+not HOW to use them.
diff --git a/docs/px.toml.in b/docs/px.toml.in
new file mode 100644
index 0000000..8cab536
--- /dev/null
+++ b/docs/px.toml.in
@@ -0,0 +1,71 @@
+[library]
+version = "@VERSION@"
+description = "Simplifyed proxy handling"
+authors = "libproxy Team"
+license = "LGPL-2.1-or-later"
+browse_url = "https://github.com/libproxy/libproxy"
+repository_url = "https://github.com/libproxy/libproxy"
+website_url = "https://libproxy.github.io/libproxy/"
+# logo_url = "libproxy.svg"
+dependencies = [
+ "GObject-2.0",
+ "Gio-2.0",
+ "GLib-2.0",
+ "Soup-3.0",
+ "curl-1.0",
+]
+devhelp = true
+search_index = true
+
+[dependencies."GObject-2.0"]
+name = "GObject"
+description = "The base type system library"
+docs_url = "https://developer.gnome.org/gobject/stable"
+
+[dependencies."Gio-2.0"]
+name = "Gio"
+description = "Gio is a library providing useful classes for general purpose I/O, networking, IPC, settings, and other high level application functionality"
+docs_url = "https://developer.gnome.org/gio/stable"
+
+[dependencies."GLib-2.0"]
+name = "GLib"
+description = "The base utility library"
+docs_url = "https://developer.gnome.org/glib/stable"
+
+[dependencies."Soup-3.0"]
+name = "Soup"
+description = "HTTP client/server library for GNOME"
+docs_url = "https://libsoup.org/libsoup-3.0/index.html"
+
+[dependencies."curl-1.0"]
+name = "cURL"
+description = "Library for transferring data"
+docs_url = "https://github.com/curl/curl"
+
+[theme]
+name = "basic"
+show_index_summary = false
+show_class_hierarchy = false
+
+[source-location]
+# The base URL for the web UI
+base_url = "https://gitlab.gnome.org/jbrummer/libproxy/-/blob/main/"
+# The format for links, using "filename" and "line" for the format
+file_format = "{filename}#L{line}"
+
+[extra]
+content_files = [
+ "architecture.md",
+ "applications.md",
+ "build-steps.md",
+ "configuration-logic.md",
+ "proxy-authentication.md",
+ "perl.md",
+ "python.md",
+ "ruby.md",
+ "vala.md",
+]
+
+content_images = [
+ "libproxy.svg"
+]
diff --git a/docs/python.md b/docs/python.md
new file mode 100644
index 0000000..8094e0b
--- /dev/null
+++ b/docs/python.md
@@ -0,0 +1,30 @@
+Title: How to use libproxy in Python
+Slug: snippets
+
+# How to use libproxy in Python
+
+```
+import gi
+gi.require_version('Libproxy', '1.0')
+from gi.repository import Libproxy
+import requests
+
+url = 'https://github.com/libproxy/libproxy'
+
+pf = Libproxy.ProxyFactory()
+proxies = pf.get_proxies(url)
+
+success = False
+for proxy in proxies:
+ response = requests.get(url) #, proxies=proxies)
+
+ if response.status_code == 200:
+ success = True
+ break
+
+if success:
+ print(f"The requested URL {url} could be retrieved using the current setup!")
+else:
+ print(f"The requested URL {url} could *NOT* be retrieved using the current setup")
+```
+
diff --git a/docs/ruby.md b/docs/ruby.md
new file mode 100644
index 0000000..ceddbd8
--- /dev/null
+++ b/docs/ruby.md
@@ -0,0 +1,20 @@
+Title: How to use libproxy in Ruby
+Slug: snippets
+
+# How to use libproxy in Ruby
+
+```
+#!/usr/bin/ruby
+
+require 'gir_ffi'
+GirFFI.setup :Libproxy
+
+pf = Libproxy::ProxyFactory.new()
+
+proxies = pf.get_proxies("https://github.com/libproxy/libproxy")
+proxies.each do |proxy|
+ puts proxy
+end
+
+pf.free()
+```
diff --git a/docs/samples.md b/docs/samples.md
new file mode 100644
index 0000000..f73aa0f
--- /dev/null
+++ b/docs/samples.md
@@ -0,0 +1,4 @@
+Title: How to use libproxy in language X?
+Slug: building
+
+# Samples - How to use libproxy in language X?
diff --git a/docs/samples/dotnet/Makefile b/docs/samples/dotnet/Makefile
new file mode 100644
index 0000000..587f83b
--- /dev/null
+++ b/docs/samples/dotnet/Makefile
@@ -0,0 +1,8 @@
+
+all: proxy.exe
+
+proxy.exe: proxy.cs
+ gmcs -pkg:libproxy-sharp-1.0 proxy.cs
+
+clean:
+ rm proxy.exe
diff --git a/docs/samples/dotnet/proxy.cs b/docs/samples/dotnet/proxy.cs
new file mode 100644
index 0000000..a8ce5e4
--- /dev/null
+++ b/docs/samples/dotnet/proxy.cs
@@ -0,0 +1,38 @@
+/*******************************************************************************
+ * libproxy - A library for proxy configuration
+ * Copyright (C) 2009 Dominique Leuenberger <dominique@leuenberger.net>
+ *
+ * This library 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.1 of the License, or (at your option) any later version.
+ *
+ * This library 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 library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ ******************************************************************************/
+
+using System;
+using libproxy;
+
+public class proxy {
+ public static int Main (string[] args)
+ {
+ if (args.Length > 0) {
+ ProxyFactory pf = new ProxyFactory();
+ string[] Proxies = pf.GetProxies(args[0]);
+ Console.WriteLine(Proxies[0]);
+ pf = null;
+ return 0;
+ } else {
+ Console.WriteLine("Please start the program with one parameter");
+ Console.WriteLine("Example: proxy.exe http://libproxy.googlecode.com/");
+ return 1;
+ }
+ }
+}
diff --git a/docs/samples/libcurl/Makefile b/docs/samples/libcurl/Makefile
new file mode 100644
index 0000000..35b4597
--- /dev/null
+++ b/docs/samples/libcurl/Makefile
@@ -0,0 +1,9 @@
+
+
+all: curlget
+
+curlget: curlget.c
+ gcc curlget.c -o curlget -Wall -lcurl -std=c99 $(shell pkg-config --libs libproxy-1.0)
+
+clean:
+ rm curlget
diff --git a/docs/samples/libcurl/curlget.c b/docs/samples/libcurl/curlget.c
new file mode 100644
index 0000000..00954e9
--- /dev/null
+++ b/docs/samples/libcurl/curlget.c
@@ -0,0 +1,108 @@
+/*******************************************************************************
+ * libproxy - A library for proxy configuration
+ * Copyright (C) 2006 Nathaniel McCallum <nathaniel@natemccallum.com>
+ * Copyright (C) 2008 Dominique Leuenberger <dominique-libproxy@leuenberger.net>
+ *
+ * This library 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.1 of the License, or (at your option) any later version.
+ *
+ * This library 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 library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ ******************************************************************************/
+
+#include "proxy.h"
+#include "curl/curl.h"
+#include <string.h>
+#include <stdlib.h>
+
+int main(int argc, char * argv[]) {
+ pxProxyFactory *pf = NULL;
+ CURL *curl = NULL;
+ CURLcode result = 1;
+
+ /* Check if we have a parameter passed, otherwise bail out... I need one */
+ if (argc < 2)
+ {
+ printf("libcurl / libproxy example implementation\n");
+ printf("=========================================\n");
+ printf("The program has to be started with one parameter\n");
+ printf("Defining the URL that should be downloaded\n\n");
+ printf("Example: %s http://code.google.com/p/libproxy/\n", argv[0]);
+ return -1;
+ }
+
+ /* Initializing curl... has to happen exactly once in the program */
+ if (curl_global_init( CURL_GLOBAL_ALL )) return -4;
+
+ /* Create pxProxyFactory object */
+ if (!(pf = px_proxy_factory_new()))
+ {
+ printf("Unable to create pxProxyFactory object!\n");
+ curl_global_cleanup();
+ return -2;
+ }
+
+ /* Create curl handle */
+ if (!(curl = curl_easy_init()))
+ {
+ printf("Unable to get libcurl handle!\n");
+ px_proxy_factory_free(pf);
+ curl_global_cleanup();
+ return -3;
+ }
+
+ /* Get the array of proxies to try */
+ char **proxies = px_proxy_factory_get_proxies(pf, argv[1]);
+
+ /* Set the URL into the curl handle */
+ curl_easy_setopt(curl, CURLOPT_URL, argv[1]);
+
+ /* Try to fetch our url using each proxy */
+ for (int i=0 ; proxies[i] ; i++)
+ {
+ if (result != 0)
+ {
+ /* Setup our proxy's config into curl */
+ curl_easy_setopt(curl, CURLOPT_PROXY, proxies[i]);
+
+ /* HTTP Proxy */
+ if (!strncmp("http", proxies[i], 4))
+ curl_easy_setopt(curl, CURLOPT_PROXYTYPE, CURLPROXY_HTTP);
+
+ /* SOCKS Proxy, is this correct??? */
+ /* What about SOCKS 4A, 5 and 5_HOSTNAME??? */
+ else if (!strncmp("socks", proxies[i], 4))
+ curl_easy_setopt(curl, CURLOPT_PROXYTYPE, CURLPROXY_SOCKS5);
+
+ /* Attempt to fetch the page */
+ result = curl_easy_perform(curl);
+ }
+
+ /* If we reached the end of the proxies array and still did not
+ succeed to conntect, let's inform the user that we failed. */
+ if (proxies[i+1] == NULL && result != 0)
+ printf ("The requested URL (%s) could not be retrieved using the current setup\n", argv[1]);
+
+ }
+
+ /* Free the proxy array */
+ px_proxy_factory_free_proxies(proxies);
+
+ /* Free the curl and libproxy handles */
+ px_proxy_factory_free(pf);
+ curl_easy_cleanup(curl);
+
+ /* Cleanup the libcurl library */
+ curl_global_cleanup();
+ return 0;
+
+}
+
diff --git a/docs/samples/perl/sample.pl b/docs/samples/perl/sample.pl
new file mode 100644
index 0000000..e8850fc
--- /dev/null
+++ b/docs/samples/perl/sample.pl
@@ -0,0 +1,7 @@
+use Net::Libproxy;
+
+$p = new Net::Libproxy;
+$proxies = $p->getProxies('http://www.google.com');
+foreach my $proxy (@$proxies) {
+ print $proxy."\n";
+}
diff --git a/docs/samples/vala/Makefile b/docs/samples/vala/Makefile
new file mode 100644
index 0000000..3e42a34
--- /dev/null
+++ b/docs/samples/vala/Makefile
@@ -0,0 +1,7 @@
+all: sample
+
+sample: sample.vala
+ valac --pkg libproxy-1.0 sample.vala
+
+clean:
+ rm sample
diff --git a/docs/samples/vala/sample.vala b/docs/samples/vala/sample.vala
new file mode 100644
index 0000000..1cec8cf
--- /dev/null
+++ b/docs/samples/vala/sample.vala
@@ -0,0 +1,9 @@
+using Libproxy;
+
+void main () {
+ var pf = new ProxyFactory ();
+ string[] proxies = pf.get_proxies ("http://www.google.com");
+ foreach (string proxy in proxies) {
+ stdout.printf ("%s\n", proxy);
+ }
+}
diff --git a/docs/vala.md b/docs/vala.md
new file mode 100644
index 0000000..b1332ac
--- /dev/null
+++ b/docs/vala.md
@@ -0,0 +1,32 @@
+Title: How to use libproxy in Vala
+Slug: snippets
+
+# How to use libproxy in Vala
+
+
+## Makefile
+
+```
+all: sample
+
+sample: sample.vala
+ valac --pkg libproxy-1.0 sample.vala
+
+clean:
+ rm sample
+```
+
+## Source
+
+```
+using px;
+
+void main() {
+ var pf = new px.ProxyFactory();
+ string[] proxies = pf.get_proxies("https://github.com/libproxy/libproxy");
+
+ foreach (string proxy in proxies) {
+ stdout.printf ("%s\n", proxy);
+ }
+}
+```
diff --git a/docs/version.xml.in b/docs/version.xml.in
new file mode 100644
index 0000000..d78bda9
--- /dev/null
+++ b/docs/version.xml.in
@@ -0,0 +1 @@
+@VERSION@