mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-07-19 00:17:51 +02:00
.gitlab-ci
.reuse
LICENSES
docs
fuzzing
gio
completion
gdbus-2.0
gvdb
inotify
kqueue
tests
win32
xdgmime
data-to-c.py
dbus-daemon.xml
gaction.c
gaction.h
gactiongroup.c
gactiongroup.h
gactiongroupexporter.c
gactiongroupexporter.h
gactionmap.c
gactionmap.h
gappinfo.c
gappinfo.h
gappinfoprivate.h
gapplication-tool.c
gapplication.c
gapplication.h
gapplicationcommandline.c
gapplicationcommandline.h
gapplicationimpl-dbus.c
gapplicationimpl.h
gasynchelper.c
gasynchelper.h
gasyncinitable.c
gasyncinitable.h
gasyncresult.c
gasyncresult.h
gbufferedinputstream.c
gbufferedinputstream.h
gbufferedoutputstream.c
gbufferedoutputstream.h
gbytesicon.c
gbytesicon.h
gcancellable.c
gcancellable.h
gcharsetconverter.c
gcharsetconverter.h
gcocoanotificationbackend.m
gcontenttype-win32.c
gcontenttype.c
gcontenttype.h
gcontenttypeprivate.h
gcontextspecificgroup.c
gcontextspecificgroup.h
gconverter.c
gconverter.h
gconverterinputstream.c
gconverterinputstream.h
gconverteroutputstream.c
gconverteroutputstream.h
gcredentials.c
gcredentials.h
gcredentialsprivate.h
gdatagrambased.c
gdatagrambased.h
gdatainputstream.c
gdatainputstream.h
gdataoutputstream.c
gdataoutputstream.h
gdbus-tool.c
gdbusactiongroup-private.h
gdbusactiongroup.c
gdbusactiongroup.h
gdbusaddress.c
gdbusaddress.h
gdbusauth.c
gdbusauth.h
gdbusauthmechanism.c
gdbusauthmechanism.h
gdbusauthmechanismanon.c
gdbusauthmechanismanon.h
gdbusauthmechanismexternal.c
gdbusauthmechanismexternal.h
gdbusauthmechanismsha1.c
gdbusauthmechanismsha1.h
gdbusauthobserver.c
gdbusauthobserver.h
gdbusconnection.c
gdbusconnection.h
gdbusdaemon.c
gdbusdaemon.h
gdbuserror.c
gdbuserror.h
gdbusinterface.c
gdbusinterface.h
gdbusinterfaceskeleton.c
gdbusinterfaceskeleton.h
gdbusintrospection.c
gdbusintrospection.h
gdbusmenumodel.c
gdbusmenumodel.h
gdbusmessage.c
gdbusmessage.h
gdbusmethodinvocation.c
gdbusmethodinvocation.h
gdbusnameowning.c
gdbusnameowning.h
gdbusnamewatching.c
gdbusnamewatching.h
gdbusobject.c
gdbusobject.h
gdbusobjectmanager.c
gdbusobjectmanager.h
gdbusobjectmanagerclient.c
gdbusobjectmanagerclient.h
gdbusobjectmanagerserver.c
gdbusobjectmanagerserver.h
gdbusobjectproxy.c
gdbusobjectproxy.h
gdbusobjectskeleton.c
gdbusobjectskeleton.h
gdbusprivate.c
gdbusprivate.h
gdbusproxy.c
gdbusproxy.h
gdbusserver.c
gdbusserver.h
gdbusutils.c
gdbusutils.h
gdebugcontroller.c
gdebugcontroller.h
gdebugcontrollerdbus.c
gdebugcontrollerdbus.h
gdelayedsettingsbackend.c
gdelayedsettingsbackend.h
gdesktopappinfo.c
gdesktopappinfo.h
gdocumentportal.c
gdocumentportal.h
gdrive.c
gdrive.h
gdtlsclientconnection.c
gdtlsclientconnection.h
gdtlsconnection.c
gdtlsconnection.h
gdtlsserverconnection.c
gdtlsserverconnection.h
gdummyfile.c
gdummyfile.h
gdummyproxyresolver.c
gdummyproxyresolver.h
gdummytlsbackend.c
gdummytlsbackend.h
gemblem.c
gemblem.h
gemblemedicon.c
gemblemedicon.h
gfdonotificationbackend.c
gfile.c
gfile.h
gfileattribute-priv.h
gfileattribute.c
gfileattribute.h
gfiledescriptorbased.c
gfiledescriptorbased.h
gfileenumerator.c
gfileenumerator.h
gfileicon.c
gfileicon.h
gfileinfo-priv.h
gfileinfo.c
gfileinfo.h
gfileinputstream.c
gfileinputstream.h
gfileiostream.c
gfileiostream.h
gfilemonitor.c
gfilemonitor.h
gfilenamecompleter.c
gfilenamecompleter.h
gfileoutputstream.c
gfileoutputstream.h
gfilterinputstream.c
gfilterinputstream.h
gfilteroutputstream.c
gfilteroutputstream.h
ggtknotificationbackend.c
ghttpproxy.c
ghttpproxy.h
gicon.c
gicon.h
ginetaddress.c
ginetaddress.h
ginetaddressmask.c
ginetaddressmask.h
ginetsocketaddress.c
ginetsocketaddress.h
ginitable.c
ginitable.h
ginputstream.c
ginputstream.h
gio-autocleanups.h
gio-querymodules.c
gio-tool-cat.c
gio-tool-copy.c
gio-tool-info.c
gio-tool-launch.c
gio-tool-list.c
gio-tool-mime.c
gio-tool-mkdir.c
gio-tool-monitor.c
gio-tool-mount.c
gio-tool-move.c
gio-tool-open.c
gio-tool-remove.c
gio-tool-rename.c
gio-tool-save.c
gio-tool-set.c
gio-tool-trash.c
gio-tool-tree.c
gio-tool.c
gio-tool.h
gio.h
gio.rc.in
gio.stp.in
gio_probes.d
gio_trace.h
gioenums.h
gioenumtypes.c.template
gioenumtypes.h.template
gioerror.c
gioerror.h
giomodule-priv.c
giomodule-priv.h
giomodule.c
giomodule.h
gioprivate.h
gioscheduler.c
gioscheduler.h
giostream.c
giostream.h
giotypes.h
giounix-private.c
giounix-private.h
giowin32-afunix.h
giowin32-priv.h
giowin32-private.c
gkeyfilesettingsbackend.c
glib-compile-resources.c
glib-compile-schemas.c
glistmodel.c
glistmodel.h
gliststore.c
gliststore.h
gloadableicon.c
gloadableicon.h
glocalfile.c
glocalfile.h
glocalfileenumerator.c
glocalfileenumerator.h
glocalfileinfo.c
glocalfileinfo.h
glocalfileinputstream.c
glocalfileinputstream.h
glocalfileiostream.c
glocalfileiostream.h
glocalfilemonitor.c
glocalfilemonitor.h
glocalfileoutputstream.c
glocalfileoutputstream.h
glocalvfs.c
glocalvfs.h
gmarshal-internal.c
gmarshal-internal.h
gmarshal-internal.list
gmemoryinputstream.c
gmemoryinputstream.h
gmemorymonitor.c
gmemorymonitor.h
gmemorymonitordbus.c
gmemorymonitordbus.h
gmemorymonitorportal.c
gmemorymonitorportal.h
gmemorymonitorwin32.c
gmemoryoutputstream.c
gmemoryoutputstream.h
gmemorysettingsbackend.c
gmenu.c
gmenu.h
gmenuexporter.c
gmenuexporter.h
gmenumodel.c
gmenumodel.h
gmount.c
gmount.h
gmountoperation.c
gmountoperation.h
gmountprivate.h
gnativesocketaddress.c
gnativesocketaddress.h
gnativevolumemonitor.c
gnativevolumemonitor.h
gnetworkaddress.c
gnetworkaddress.h
gnetworking.c
gnetworking.h.in
gnetworkingprivate.h
gnetworkmonitor.c
gnetworkmonitor.h
gnetworkmonitorbase.c
gnetworkmonitorbase.h
gnetworkmonitornetlink.c
gnetworkmonitornetlink.h
gnetworkmonitornm.c
gnetworkmonitornm.h
gnetworkmonitorportal.c
gnetworkmonitorportal.h
gnetworkservice.c
gnetworkservice.h
gnextstepsettingsbackend.m
gnotification-private.h
gnotification.c
gnotification.h
gnotificationbackend.c
gnotificationbackend.h
gnullsettingsbackend.c
gopenuriportal.c
gopenuriportal.h
gosxappinfo.h
gosxappinfo.m
gosxcontenttype.m
goutputstream.c
goutputstream.h
gpermission.c
gpermission.h
gpollableinputstream.c
gpollableinputstream.h
gpollableoutputstream.c
gpollableoutputstream.h
gpollableutils.c
gpollableutils.h
gpollfilemonitor.c
gpollfilemonitor.h
gportalnotificationbackend.c
gportalsupport.c
gportalsupport.h
gpowerprofilemonitor.c
gpowerprofilemonitor.h
gpowerprofilemonitordbus.c
gpowerprofilemonitordbus.h
gpowerprofilemonitorportal.c
gpowerprofilemonitorportal.h
gpropertyaction.c
gpropertyaction.h
gproxy.c
gproxy.h
gproxyaddress.c
gproxyaddress.h
gproxyaddressenumerator.c
gproxyaddressenumerator.h
gproxyresolver.c
gproxyresolver.h
gproxyresolverportal.c
gproxyresolverportal.h
gregistrysettingsbackend.c
gregistrysettingsbackend.h
gremoteactiongroup.c
gremoteactiongroup.h
gresolver.c
gresolver.h
gresource-tool.c
gresource.c
gresource.h
gresourcefile.c
gresourcefile.h
gschema.dtd
gschema.its
gschema.loc
gseekable.c
gseekable.h
gsettings-mapping.c
gsettings-mapping.h
gsettings-tool.c
gsettings.c
gsettings.h
gsettingsbackend.c
gsettingsbackend.h
gsettingsbackendinternal.h
gsettingsschema-internal.h
gsettingsschema.c
gsettingsschema.h
gsimpleaction.c
gsimpleaction.h
gsimpleactiongroup.c
gsimpleactiongroup.h
gsimpleasyncresult.c
gsimpleasyncresult.h
gsimpleiostream.c
gsimpleiostream.h
gsimplepermission.c
gsimplepermission.h
gsimpleproxyresolver.c
gsimpleproxyresolver.h
gsocket.c
gsocket.h
gsocketaddress.c
gsocketaddress.h
gsocketaddressenumerator.c
gsocketaddressenumerator.h
gsocketclient.c
gsocketclient.h
gsocketconnectable.c
gsocketconnectable.h
gsocketconnection.c
gsocketconnection.h
gsocketcontrolmessage.c
gsocketcontrolmessage.h
gsocketinputstream.c
gsocketinputstream.h
gsocketlistener.c
gsocketlistener.h
gsocketoutputstream.c
gsocketoutputstream.h
gsocketservice.c
gsocketservice.h
gsocks4aproxy.c
gsocks4aproxy.h
gsocks4proxy.c
gsocks4proxy.h
gsocks5proxy.c
gsocks5proxy.h
gsrvtarget.c
gsrvtarget.h
gsubprocess.c
gsubprocess.h
gsubprocesslauncher-private.h
gsubprocesslauncher.c
gsubprocesslauncher.h
gtask.c
gtask.h
gtcpconnection.c
gtcpconnection.h
gtcpwrapperconnection.c
gtcpwrapperconnection.h
gtestdbus.c
gtestdbus.h
gthemedicon.c
gthemedicon.h
gthreadedresolver.c
gthreadedresolver.h
gthreadedsocketservice.c
gthreadedsocketservice.h
gtlsbackend.c
gtlsbackend.h
gtlscertificate.c
gtlscertificate.h
gtlsclientconnection.c
gtlsclientconnection.h
gtlsconnection.c
gtlsconnection.h
gtlsdatabase.c
gtlsdatabase.h
gtlsfiledatabase.c
gtlsfiledatabase.h
gtlsinteraction.c
gtlsinteraction.h
gtlspassword.c
gtlspassword.h
gtlsserverconnection.c
gtlsserverconnection.h
gtrashportal.c
gtrashportal.h
gunionvolumemonitor.c
gunionvolumemonitor.h
gunixconnection.c
gunixconnection.h
gunixcredentialsmessage.c
gunixcredentialsmessage.h
gunixfdlist.c
gunixfdlist.h
gunixfdmessage.c
gunixfdmessage.h
gunixinputstream.c
gunixinputstream.h
gunixmount.c
gunixmount.h
gunixmounts.c
gunixmounts.h
gunixoutputstream.c
gunixoutputstream.h
gunixsocketaddress.c
gunixsocketaddress.h
gunixvolume.c
gunixvolume.h
gunixvolumemonitor.c
gunixvolumemonitor.h
gvfs.c
gvfs.h
gvolume.c
gvolume.h
gvolumemonitor.c
gvolumemonitor.h
gwin32api-application-activation-manager.h
gwin32api-iterator.h
gwin32api-misc.h
gwin32api-package.h
gwin32api-storage.h
gwin32appinfo.c
gwin32appinfo.h
gwin32file-sync-stream.c
gwin32file-sync-stream.h
gwin32inputstream.c
gwin32inputstream.h
gwin32mount.c
gwin32mount.h
gwin32networkmonitor.c
gwin32networkmonitor.h
gwin32notificationbackend.c
gwin32outputstream.c
gwin32outputstream.h
gwin32packageparser.c
gwin32packageparser.h
gwin32registrykey.c
gwin32registrykey.h
gwin32sid.c
gwin32sid.h
gwin32volumemonitor.c
gwin32volumemonitor.h
gzlibcompressor.c
gzlibcompressor.h
gzlibdecompressor.c
gzlibdecompressor.h
meson.build
org.freedesktop.portal.Documents.xml
org.freedesktop.portal.OpenURI.xml
org.freedesktop.portal.ProxyResolver.xml
org.freedesktop.portal.Trash.xml
strinfo.c
thumbnail-verify.c
thumbnail-verify.h
glib
gmodule
gobject
gthread
m4macros
po
subprojects
tests
tools
.clang-format
.dir-locals.el
.editorconfig
.gitignore
.gitlab-ci.yml
.lcovrc
CODE_OF_CONDUCT.md
CONTRIBUTING.md
COPYING
HACKING
INSTALL.md
NEWS
README.md
README.win32.md
SECURITY.md
glib.doap
meson.build
meson_options.txt
msvc_recommended_pragmas.h
Add SPDX license (but not copyright) headers to all files which follow a certain pattern in their existing non-machine-readable header comment. This commit was entirely generated using the command: ``` git ls-files gio/*.[ch] | xargs perl -0777 -pi -e 's/\n \*\n \* This library is free software; you can redistribute it and\/or\n \* modify it under the terms of the GNU Lesser General Public/\n \*\n \* SPDX-License-Identifier: LGPL-2.1-or-later\n \*\n \* This library is free software; you can redistribute it and\/or\n \* modify it under the terms of the GNU Lesser General Public/igs' ``` Signed-off-by: Philip Withnall <pwithnall@endlessos.org> Helps: #1415
419 lines
12 KiB
C
419 lines
12 KiB
C
/* GIO - GLib Input, Output and Streaming Library
|
|
*
|
|
* Copyright (C) 2010 Collabora, Ltd.
|
|
* Copyright (C) 2014 Red Hat, Inc.
|
|
*
|
|
* SPDX-License-Identifier: LGPL-2.1-or-later
|
|
*
|
|
* 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, see <http://www.gnu.org/licenses/>.
|
|
*
|
|
* Author: Nicolas Dufresne <nicolas.dufresne@collabora.co.uk>
|
|
* Marc-André Lureau <marcandre.lureau@redhat.com>
|
|
*/
|
|
|
|
#include "config.h"
|
|
|
|
#include "ghttpproxy.h"
|
|
|
|
#include <string.h>
|
|
#include <stdlib.h>
|
|
|
|
#include "giomodule.h"
|
|
#include "giomodule-priv.h"
|
|
#include "giostream.h"
|
|
#include "ginputstream.h"
|
|
#include "glibintl.h"
|
|
#include "goutputstream.h"
|
|
#include "gproxy.h"
|
|
#include "gproxyaddress.h"
|
|
#include "gsocketconnectable.h"
|
|
#include "gtask.h"
|
|
#include "gtlsclientconnection.h"
|
|
#include "gtlsconnection.h"
|
|
|
|
|
|
struct _GHttpProxy
|
|
{
|
|
GObject parent;
|
|
};
|
|
|
|
struct _GHttpProxyClass
|
|
{
|
|
GObjectClass parent_class;
|
|
};
|
|
|
|
static void g_http_proxy_iface_init (GProxyInterface *proxy_iface);
|
|
|
|
#define g_http_proxy_get_type _g_http_proxy_get_type
|
|
G_DEFINE_TYPE_WITH_CODE (GHttpProxy, g_http_proxy, G_TYPE_OBJECT,
|
|
G_IMPLEMENT_INTERFACE (G_TYPE_PROXY,
|
|
g_http_proxy_iface_init)
|
|
_g_io_modules_ensure_extension_points_registered ();
|
|
g_io_extension_point_implement (G_PROXY_EXTENSION_POINT_NAME,
|
|
g_define_type_id,
|
|
"http",
|
|
0))
|
|
|
|
static void
|
|
g_http_proxy_init (GHttpProxy *proxy)
|
|
{
|
|
}
|
|
|
|
static gchar *
|
|
create_request (GProxyAddress *proxy_address,
|
|
gboolean *has_cred,
|
|
GError **error)
|
|
{
|
|
const gchar *hostname;
|
|
gint port;
|
|
const gchar *username;
|
|
const gchar *password;
|
|
GString *request;
|
|
gchar *ascii_hostname;
|
|
|
|
if (has_cred)
|
|
*has_cred = FALSE;
|
|
|
|
hostname = g_proxy_address_get_destination_hostname (proxy_address);
|
|
ascii_hostname = g_hostname_to_ascii (hostname);
|
|
if (!ascii_hostname)
|
|
{
|
|
g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED,
|
|
_("Invalid hostname"));
|
|
return NULL;
|
|
}
|
|
port = g_proxy_address_get_destination_port (proxy_address);
|
|
username = g_proxy_address_get_username (proxy_address);
|
|
password = g_proxy_address_get_password (proxy_address);
|
|
|
|
request = g_string_new (NULL);
|
|
|
|
g_string_append_printf (request,
|
|
"CONNECT %s:%i HTTP/1.0\r\n"
|
|
"Host: %s:%i\r\n"
|
|
"Proxy-Connection: keep-alive\r\n"
|
|
"User-Agent: GLib/%i.%i\r\n",
|
|
ascii_hostname, port,
|
|
ascii_hostname, port,
|
|
GLIB_MAJOR_VERSION, GLIB_MINOR_VERSION);
|
|
g_free (ascii_hostname);
|
|
|
|
if (username != NULL && password != NULL)
|
|
{
|
|
gchar *cred;
|
|
gchar *base64_cred;
|
|
|
|
if (has_cred)
|
|
*has_cred = TRUE;
|
|
|
|
cred = g_strdup_printf ("%s:%s", username, password);
|
|
base64_cred = g_base64_encode ((guchar *) cred, strlen (cred));
|
|
g_free (cred);
|
|
g_string_append_printf (request,
|
|
"Proxy-Authorization: Basic %s\r\n",
|
|
base64_cred);
|
|
g_free (base64_cred);
|
|
}
|
|
|
|
g_string_append (request, "\r\n");
|
|
|
|
return g_string_free (request, FALSE);
|
|
}
|
|
|
|
static gboolean
|
|
check_reply (const gchar *buffer,
|
|
gboolean has_cred,
|
|
GError **error)
|
|
{
|
|
gint err_code;
|
|
const gchar *ptr = buffer + 7;
|
|
|
|
if (strncmp (buffer, "HTTP/1.", 7) != 0 || (*ptr != '0' && *ptr != '1'))
|
|
{
|
|
g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_PROXY_FAILED,
|
|
_("Bad HTTP proxy reply"));
|
|
return FALSE;
|
|
}
|
|
|
|
ptr++;
|
|
while (*ptr == ' ')
|
|
ptr++;
|
|
|
|
err_code = atoi (ptr);
|
|
|
|
if (err_code < 200 || err_code >= 300)
|
|
{
|
|
switch (err_code)
|
|
{
|
|
case 403:
|
|
g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_PROXY_NOT_ALLOWED,
|
|
_("HTTP proxy connection not allowed"));
|
|
break;
|
|
case 407:
|
|
if (has_cred)
|
|
g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_PROXY_AUTH_FAILED,
|
|
_("HTTP proxy authentication failed"));
|
|
else
|
|
g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_PROXY_NEED_AUTH,
|
|
_("HTTP proxy authentication required"));
|
|
break;
|
|
default:
|
|
g_set_error (error, G_IO_ERROR, G_IO_ERROR_PROXY_FAILED,
|
|
_("HTTP proxy connection failed: %i"), err_code);
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
#define HTTP_END_MARKER "\r\n\r\n"
|
|
|
|
static GIOStream *
|
|
g_http_proxy_connect (GProxy *proxy,
|
|
GIOStream *io_stream,
|
|
GProxyAddress *proxy_address,
|
|
GCancellable *cancellable,
|
|
GError **error)
|
|
{
|
|
GInputStream *in;
|
|
GOutputStream *out;
|
|
gchar *buffer = NULL;
|
|
gsize buffer_length;
|
|
gsize bytes_read;
|
|
gboolean has_cred;
|
|
GIOStream *tlsconn = NULL;
|
|
|
|
if (G_IS_HTTPS_PROXY (proxy))
|
|
{
|
|
tlsconn = g_tls_client_connection_new (io_stream,
|
|
G_SOCKET_CONNECTABLE (proxy_address),
|
|
error);
|
|
if (!tlsconn)
|
|
goto error;
|
|
|
|
#ifdef DEBUG
|
|
{
|
|
GTlsCertificateFlags tls_validation_flags = G_TLS_CERTIFICATE_VALIDATE_ALL;
|
|
|
|
tls_validation_flags &= ~(G_TLS_CERTIFICATE_UNKNOWN_CA | G_TLS_CERTIFICATE_BAD_IDENTITY);
|
|
g_tls_client_connection_set_validation_flags (G_TLS_CLIENT_CONNECTION (tlsconn),
|
|
tls_validation_flags);
|
|
}
|
|
#endif
|
|
|
|
if (!g_tls_connection_handshake (G_TLS_CONNECTION (tlsconn), cancellable, error))
|
|
goto error;
|
|
|
|
io_stream = tlsconn;
|
|
}
|
|
|
|
in = g_io_stream_get_input_stream (io_stream);
|
|
out = g_io_stream_get_output_stream (io_stream);
|
|
|
|
buffer = create_request (proxy_address, &has_cred, error);
|
|
if (!buffer)
|
|
goto error;
|
|
if (!g_output_stream_write_all (out, buffer, strlen (buffer), NULL,
|
|
cancellable, error))
|
|
goto error;
|
|
|
|
g_free (buffer);
|
|
|
|
bytes_read = 0;
|
|
buffer_length = 1024;
|
|
buffer = g_malloc (buffer_length);
|
|
|
|
/* Read byte-by-byte instead of using GDataInputStream
|
|
* since we do not want to read beyond the end marker
|
|
*/
|
|
do
|
|
{
|
|
gssize signed_nread;
|
|
gsize nread;
|
|
|
|
signed_nread =
|
|
g_input_stream_read (in, buffer + bytes_read, 1, cancellable, error);
|
|
if (signed_nread == -1)
|
|
goto error;
|
|
|
|
nread = signed_nread;
|
|
if (nread == 0)
|
|
break;
|
|
|
|
++bytes_read;
|
|
|
|
if (bytes_read == buffer_length)
|
|
{
|
|
/* HTTP specifications does not defines any upper limit for
|
|
* headers. But, the most usual size used seems to be 8KB.
|
|
* Yet, the biggest we found was Tomcat's HTTP headers whose
|
|
* size is 48K. So, for a reasonable error margin, let's accept
|
|
* a header with a twice as large size but no more: 96KB */
|
|
if (buffer_length > 98304)
|
|
{
|
|
g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_PROXY_FAILED,
|
|
_("HTTP proxy response too big"));
|
|
goto error;
|
|
}
|
|
buffer_length = 2 * buffer_length;
|
|
buffer = g_realloc (buffer, buffer_length);
|
|
}
|
|
|
|
*(buffer + bytes_read) = '\0';
|
|
|
|
if (g_str_has_suffix (buffer, HTTP_END_MARKER))
|
|
break;
|
|
}
|
|
while (TRUE);
|
|
|
|
if (bytes_read == 0)
|
|
{
|
|
g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_PROXY_FAILED,
|
|
_("HTTP proxy server closed connection unexpectedly."));
|
|
goto error;
|
|
}
|
|
|
|
if (!check_reply (buffer, has_cred, error))
|
|
goto error;
|
|
|
|
g_free (buffer);
|
|
|
|
g_object_ref (io_stream);
|
|
g_clear_object (&tlsconn);
|
|
|
|
return io_stream;
|
|
|
|
error:
|
|
g_clear_object (&tlsconn);
|
|
g_free (buffer);
|
|
return NULL;
|
|
}
|
|
|
|
typedef struct
|
|
{
|
|
GIOStream *io_stream;
|
|
GProxyAddress *proxy_address;
|
|
} ConnectAsyncData;
|
|
|
|
static void
|
|
free_connect_data (ConnectAsyncData *data)
|
|
{
|
|
g_object_unref (data->io_stream);
|
|
g_object_unref (data->proxy_address);
|
|
g_slice_free (ConnectAsyncData, data);
|
|
}
|
|
|
|
static void
|
|
connect_thread (GTask *task,
|
|
gpointer source_object,
|
|
gpointer task_data,
|
|
GCancellable *cancellable)
|
|
{
|
|
GProxy *proxy = source_object;
|
|
ConnectAsyncData *data = task_data;
|
|
GIOStream *res;
|
|
GError *error = NULL;
|
|
|
|
res = g_http_proxy_connect (proxy, data->io_stream, data->proxy_address,
|
|
cancellable, &error);
|
|
|
|
if (res == NULL)
|
|
g_task_return_error (task, error);
|
|
else
|
|
g_task_return_pointer (task, res, g_object_unref);
|
|
}
|
|
|
|
static void
|
|
g_http_proxy_connect_async (GProxy *proxy,
|
|
GIOStream *io_stream,
|
|
GProxyAddress *proxy_address,
|
|
GCancellable *cancellable,
|
|
GAsyncReadyCallback callback,
|
|
gpointer user_data)
|
|
{
|
|
ConnectAsyncData *data;
|
|
GTask *task;
|
|
|
|
data = g_slice_new0 (ConnectAsyncData);
|
|
data->io_stream = g_object_ref (io_stream);
|
|
data->proxy_address = g_object_ref (proxy_address);
|
|
|
|
task = g_task_new (proxy, cancellable, callback, user_data);
|
|
g_task_set_source_tag (task, g_http_proxy_connect_async);
|
|
g_task_set_task_data (task, data, (GDestroyNotify) free_connect_data);
|
|
|
|
g_task_run_in_thread (task, connect_thread);
|
|
g_object_unref (task);
|
|
}
|
|
|
|
static GIOStream *
|
|
g_http_proxy_connect_finish (GProxy *proxy,
|
|
GAsyncResult *result,
|
|
GError **error)
|
|
{
|
|
return g_task_propagate_pointer (G_TASK (result), error);
|
|
}
|
|
|
|
static gboolean
|
|
g_http_proxy_supports_hostname (GProxy *proxy)
|
|
{
|
|
return TRUE;
|
|
}
|
|
|
|
static void
|
|
g_http_proxy_class_init (GHttpProxyClass *class)
|
|
{
|
|
}
|
|
|
|
static void
|
|
g_http_proxy_iface_init (GProxyInterface *proxy_iface)
|
|
{
|
|
proxy_iface->connect = g_http_proxy_connect;
|
|
proxy_iface->connect_async = g_http_proxy_connect_async;
|
|
proxy_iface->connect_finish = g_http_proxy_connect_finish;
|
|
proxy_iface->supports_hostname = g_http_proxy_supports_hostname;
|
|
}
|
|
|
|
struct _GHttpsProxy
|
|
{
|
|
GHttpProxy parent;
|
|
};
|
|
|
|
struct _GHttpsProxyClass
|
|
{
|
|
GHttpProxyClass parent_class;
|
|
};
|
|
|
|
#define g_https_proxy_get_type _g_https_proxy_get_type
|
|
G_DEFINE_TYPE_WITH_CODE (GHttpsProxy, g_https_proxy, G_TYPE_HTTP_PROXY,
|
|
G_IMPLEMENT_INTERFACE (G_TYPE_PROXY,
|
|
g_http_proxy_iface_init)
|
|
_g_io_modules_ensure_extension_points_registered ();
|
|
g_io_extension_point_implement (G_PROXY_EXTENSION_POINT_NAME,
|
|
g_define_type_id,
|
|
"https",
|
|
0))
|
|
|
|
static void
|
|
g_https_proxy_init (GHttpsProxy *proxy)
|
|
{
|
|
}
|
|
|
|
static void
|
|
g_https_proxy_class_init (GHttpsProxyClass *class)
|
|
{
|
|
}
|