1 /* GIO - GLib Input, Output and Streaming Library
3 * Copyright (C) 2006-2007 Red Hat, Inc.
4 * Copyright (C) 2008 Novell, Inc.
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General
17 * Public License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
19 * Boston, MA 02111-1307, USA.
21 * Author: Alexander Larsson <alexl@redhat.com>
22 * Author: Tor Lillqvist <tml@novell.com>
27 #include "giomodule.h"
30 #include "gwinhttpfile.h"
31 #include "gwinhttpvfs.h"
35 #define g_winhttp_vfs_get_type _g_winhttp_vfs_get_type
36 G_DEFINE_TYPE_WITH_CODE (GWinHttpVfs, g_winhttp_vfs, G_TYPE_VFS,
37 g_io_extension_point_implement (G_VFS_EXTENSION_POINT_NAME,
42 static const gchar *winhttp_uri_schemes[] = { "http", "https" };
45 g_winhttp_vfs_finalize (GObject *object)
49 vfs = G_WINHTTP_VFS (object);
51 (G_WINHTTP_VFS_GET_CLASS (vfs)->pWinHttpCloseHandle) (vfs->session);
55 g_object_unref (vfs->wrapped_vfs);
56 vfs->wrapped_vfs = NULL;
58 G_OBJECT_CLASS (g_winhttp_vfs_parent_class)->finalize (object);
62 g_winhttp_vfs_init (GWinHttpVfs *vfs)
66 vfs->wrapped_vfs = g_vfs_get_local ();
68 wagent = g_utf8_to_utf16 (g_get_prgname (), -1, NULL, NULL, NULL);
71 wagent = g_utf8_to_utf16 ("GWinHttpVfs", -1, NULL, NULL, NULL);
73 vfs->session = (G_WINHTTP_VFS_GET_CLASS (vfs)->pWinHttpOpen)
75 WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,
76 WINHTTP_NO_PROXY_NAME,
77 WINHTTP_NO_PROXY_BYPASS,
84 * Returns a new #GVfs handle for a WinHttp vfs.
86 * Returns: a new #GVfs handle.
89 _g_winhttp_vfs_new (void)
91 return g_object_new (G_TYPE_WINHTTP_VFS, NULL);
95 g_winhttp_vfs_get_file_for_path (GVfs *vfs,
98 return g_vfs_get_file_for_path (G_WINHTTP_VFS (vfs)->wrapped_vfs, path);
102 g_winhttp_vfs_get_file_for_uri (GVfs *vfs,
105 GWinHttpVfs *winhttp_vfs = G_WINHTTP_VFS (vfs);
108 /* If it matches one of "our" schemes, handle it */
109 for (i = 0; i < G_N_ELEMENTS (winhttp_uri_schemes); i++)
110 if (g_ascii_strncasecmp (uri, winhttp_uri_schemes[i], strlen (winhttp_uri_schemes[i])) == 0 &&
111 uri[strlen (winhttp_uri_schemes[i])] == ':')
112 return _g_winhttp_file_new (winhttp_vfs, uri);
114 /* For other URIs fallback to the wrapped GVfs */
115 return g_vfs_parse_name (winhttp_vfs->wrapped_vfs, uri);
118 static const gchar * const *
119 g_winhttp_vfs_get_supported_uri_schemes (GVfs *vfs)
121 GWinHttpVfs *winhttp_vfs = G_WINHTTP_VFS (vfs);
122 const gchar * const *wrapped_vfs_uri_schemes = g_vfs_get_supported_uri_schemes (winhttp_vfs->wrapped_vfs);
124 const gchar **retval;
127 while (wrapped_vfs_uri_schemes[n] != NULL)
130 retval = g_new (const gchar *, n + G_N_ELEMENTS (winhttp_uri_schemes) + 1);
132 while (wrapped_vfs_uri_schemes[n] != NULL)
134 retval[n] = wrapped_vfs_uri_schemes[n];
138 for (i = 0; i < G_N_ELEMENTS (winhttp_uri_schemes); i++)
140 retval[n] = winhttp_uri_schemes[i];
150 g_winhttp_vfs_parse_name (GVfs *vfs,
151 const char *parse_name)
153 GWinHttpVfs *winhttp_vfs = G_WINHTTP_VFS (vfs);
155 g_return_val_if_fail (G_IS_VFS (vfs), NULL);
156 g_return_val_if_fail (parse_name != NULL, NULL);
158 /* For plain file paths fallback to the wrapped GVfs */
159 if (g_path_is_absolute (parse_name))
160 return g_vfs_parse_name (winhttp_vfs->wrapped_vfs, parse_name);
162 /* Otherwise assume it is an URI, so pass on to
163 * g_winhttp_vfs_get_file_for_uri().
165 return g_winhttp_vfs_get_file_for_uri (vfs, parse_name);
169 g_winhttp_vfs_is_active (GVfs *vfs)
175 g_winhttp_vfs_class_init (GWinHttpVfsClass *class)
177 GObjectClass *object_class;
178 GVfsClass *vfs_class;
181 object_class = (GObjectClass *) class;
183 object_class->finalize = g_winhttp_vfs_finalize;
185 vfs_class = G_VFS_CLASS (class);
187 vfs_class->is_active = g_winhttp_vfs_is_active;
188 vfs_class->get_file_for_path = g_winhttp_vfs_get_file_for_path;
189 vfs_class->get_file_for_uri = g_winhttp_vfs_get_file_for_uri;
190 vfs_class->get_supported_uri_schemes = g_winhttp_vfs_get_supported_uri_schemes;
191 vfs_class->parse_name = g_winhttp_vfs_parse_name;
193 winhttp = LoadLibrary ("winhttp.dll");
196 class->pWinHttpCloseHandle = (BOOL (WINAPI *) (HINTERNET)) GetProcAddress (winhttp, "WinHttpCloseHandle");
197 class->pWinHttpCrackUrl = (BOOL (WINAPI *) (LPCWSTR,DWORD,DWORD,LPURL_COMPONENTS)) GetProcAddress (winhttp, "WinHttpCrackUrl");
198 class->pWinHttpConnect = (HINTERNET (WINAPI *) (HINTERNET,LPCWSTR,INTERNET_PORT,DWORD)) GetProcAddress (winhttp, "WinHttpConnect");
199 class->pWinHttpCreateUrl = (BOOL (WINAPI *) (LPURL_COMPONENTS,DWORD,LPWSTR,LPDWORD)) GetProcAddress (winhttp, "WinHttpCreateUrl");
200 class->pWinHttpOpen = (HINTERNET (WINAPI *) (LPCWSTR,DWORD,LPCWSTR,LPCWSTR,DWORD)) GetProcAddress (winhttp, "WinHttpOpen");
201 class->pWinHttpOpenRequest = (HINTERNET (WINAPI *) (HINTERNET,LPCWSTR,LPCWSTR,LPCWSTR,LPCWSTR,LPCWSTR*,DWORD)) GetProcAddress (winhttp, "WinHttpOpenRequest");
202 class->pWinHttpQueryDataAvailable = (BOOL (WINAPI *) (HINTERNET,LPDWORD)) GetProcAddress (winhttp, "WinHttpQueryDataAvailable");
203 class->pWinHttpQueryHeaders = (BOOL (WINAPI *) (HINTERNET,DWORD,LPCWSTR,LPVOID,LPDWORD,LPDWORD)) GetProcAddress (winhttp, "WinHttpQueryHeaders");
204 class->pWinHttpReadData = (BOOL (WINAPI *) (HINTERNET,LPVOID,DWORD,LPDWORD)) GetProcAddress (winhttp, "WinHttpReadData");
205 class->pWinHttpReceiveResponse = (BOOL (WINAPI *) (HINTERNET,LPVOID)) GetProcAddress (winhttp, "WinHttpReceiveResponse");
206 class->pWinHttpSendRequest = (BOOL (WINAPI *) (HINTERNET,LPCWSTR,DWORD,LPVOID,DWORD,DWORD,DWORD_PTR)) GetProcAddress (winhttp, "WinHttpSendRequest");
207 class->pWinHttpWriteData = (BOOL (WINAPI *) (HINTERNET,LPCVOID,DWORD,LPDWORD)) GetProcAddress (winhttp, "WinHttpWriteData");
212 _g_winhttp_error_message (DWORD error_code)
214 /* The FormatMessage() API that g_win32_error_message() uses doesn't
215 * seem to know about WinHttp errors, unfortunately.
217 if (error_code >= WINHTTP_ERROR_BASE && error_code < WINHTTP_ERROR_BASE + 200)
221 /* FIXME: Use meaningful error messages */
222 #define CASE(x) case ERROR_WINHTTP_##x: return g_strdup ("WinHttp error: " #x);
223 CASE (AUTO_PROXY_SERVICE_ERROR);
224 CASE (AUTODETECTION_FAILED);
225 CASE (BAD_AUTO_PROXY_SCRIPT);
226 CASE (CANNOT_CALL_AFTER_OPEN);
227 CASE (CANNOT_CALL_AFTER_SEND);
228 CASE (CANNOT_CALL_BEFORE_OPEN);
229 CASE (CANNOT_CALL_BEFORE_SEND);
230 CASE (CANNOT_CONNECT);
231 CASE (CHUNKED_ENCODING_HEADER_SIZE_OVERFLOW);
232 CASE (CLIENT_AUTH_CERT_NEEDED);
233 CASE (CONNECTION_ERROR);
234 CASE (HEADER_ALREADY_EXISTS);
235 CASE (HEADER_COUNT_EXCEEDED);
236 CASE (HEADER_NOT_FOUND);
237 CASE (HEADER_SIZE_OVERFLOW);
238 CASE (INCORRECT_HANDLE_STATE);
239 CASE (INCORRECT_HANDLE_TYPE);
240 CASE (INTERNAL_ERROR);
241 CASE (INVALID_OPTION);
242 CASE (INVALID_QUERY_REQUEST);
243 CASE (INVALID_SERVER_RESPONSE);
245 CASE (LOGIN_FAILURE);
246 CASE (NAME_NOT_RESOLVED);
247 CASE (NOT_INITIALIZED);
248 CASE (OPERATION_CANCELLED);
249 CASE (OPTION_NOT_SETTABLE);
250 CASE (OUT_OF_HANDLES);
251 CASE (REDIRECT_FAILED);
252 CASE (RESEND_REQUEST);
253 CASE (RESPONSE_DRAIN_OVERFLOW);
254 CASE (SECURE_CERT_CN_INVALID);
255 CASE (SECURE_CERT_DATE_INVALID);
256 CASE (SECURE_CERT_REV_FAILED);
257 CASE (SECURE_CERT_REVOKED);
258 CASE (SECURE_CERT_WRONG_USAGE);
259 CASE (SECURE_CHANNEL_ERROR);
260 CASE (SECURE_FAILURE);
261 CASE (SECURE_INVALID_CA);
262 CASE (SECURE_INVALID_CERT);
265 CASE (UNABLE_TO_DOWNLOAD_SCRIPT);
266 CASE (UNRECOGNIZED_SCHEME);
269 return g_strdup_printf ("WinHttp error %ld", error_code);
273 return g_win32_error_message (error_code);