glib r7350 - in trunk/gio: . win32
- From: tml svn gnome org
- To: svn-commits-list gnome org
- Subject: glib r7350 - in trunk/gio: . win32
- Date: Wed, 13 Aug 2008 19:39:49 +0000 (UTC)
Author: tml
Date: Wed Aug 13 19:39:49 2008
New Revision: 7350
URL: http://svn.gnome.org/viewvc/glib?rev=7350&view=rev
Log:
2008-08-13 Tor Lillqvist <tml novell com>
* win32/gwinhttpvfs.c
* win32/gwinhttpvfs.h
* win32/gwinhttpfile.c
* win32/gwinhttpfileinputstream.c
* win32/gwinhttpfileoutputstream.c: Refactor some common code
snippets into helper functions. Check HTTP response status
codes. Implement g_winhttp_file_query_info(), looking at
Content-Length, Content-Type and Last-Modified.
* win32/winhttp.h: Add some symbolic constants that are not
publicly documented. Just a handful, so it should be OK to use
information from the Windows SDK's headers.
Modified:
trunk/gio/ChangeLog
trunk/gio/win32/gwinhttpfile.c
trunk/gio/win32/gwinhttpfileinputstream.c
trunk/gio/win32/gwinhttpfileoutputstream.c
trunk/gio/win32/gwinhttpvfs.c
trunk/gio/win32/gwinhttpvfs.h
trunk/gio/win32/winhttp.h
Modified: trunk/gio/win32/gwinhttpfile.c
==============================================================================
--- trunk/gio/win32/gwinhttpfile.c (original)
+++ trunk/gio/win32/gwinhttpfile.c Wed Aug 13 19:39:49 2008
@@ -1,5 +1,5 @@
/* GIO - GLib Input, Output and Streaming Library
- *
+ *
* Copyright (C) 2006-2007 Red Hat, Inc.
* Copyright (C) 2008 Novell, Inc.
*
@@ -28,6 +28,7 @@
#include "gfile.h"
#include "gfileattribute.h"
+#include "gfileinfo.h"
#include "gwinhttpfile.h"
#include "gwinhttpfileinputstream.h"
#include "gwinhttpfileoutputstream.h"
@@ -78,7 +79,7 @@
* _g_winhttp_file_new:
* @vfs: GWinHttpVfs to use
* @uri: URI of the GWinHttpFile to create.
- *
+ *
* Returns: new winhttp #GFile.
**/
GFile *
@@ -129,7 +130,7 @@
g_free (wuri);
return NULL;
}
-
+
g_free (wuri);
return G_FILE (file);
}
@@ -206,6 +207,17 @@
retval = g_utf16_to_utf8 (wuri, -1, NULL, NULL, NULL);
g_free (wuri);
+ if (g_str_has_prefix (retval, "http://:@"))
+ {
+ memmove (retval + 7, retval + 9, strlen (retval) - 9);
+ retval[strlen (retval) - 2] = '\0';
+ }
+ else if (g_str_has_prefix (retval, "https://:@"))
+ {
+ memmove (retval + 8, retval + 10, strlen (retval) - 10);
+ retval[strlen (retval) - 2] = '\0';
+ }
+
return retval;
}
@@ -230,7 +242,7 @@
uri = g_winhttp_file_get_uri (file);
if (uri == NULL)
return NULL;
-
+
last_slash = strrchr (uri, '/');
if (last_slash == NULL || *(last_slash+1) == 0)
{
@@ -245,7 +257,7 @@
parent = _g_winhttp_file_new (winhttp_file->vfs, uri);
g_free (uri);
-
+
return parent;
}
@@ -282,12 +294,12 @@
g_free (uri1);
g_free (uri2);
-
+
return retval;
}
static const char *
-match_prefix (const char *path,
+match_prefix (const char *path,
const char *prefix)
{
int prefix_len;
@@ -295,10 +307,10 @@
prefix_len = strlen (prefix);
if (strncmp (path, prefix, prefix_len) != 0)
return NULL;
-
+
if (prefix_len > 0 && prefix[prefix_len-1] == '/')
prefix_len--;
-
+
return path + prefix_len;
}
@@ -334,7 +346,7 @@
char *retval;
remainder = match_prefix (descendant_uri, parent_uri);
-
+
if (remainder != NULL && *remainder == '/')
retval = g_strdup (remainder + 1);
else
@@ -379,7 +391,7 @@
child->url.dwUrlPathLength = 2*(wcslen (wnew_path)+1);
child->url.lpszExtraInfo = NULL;
child->url.dwExtraInfoLength = 0;
-
+
return (GFile *) child;
}
@@ -394,15 +406,14 @@
basename = g_locale_from_utf8 (display_name, -1, NULL, NULL, NULL);
if (basename == NULL)
{
- g_set_error (error, G_IO_ERROR,
- G_IO_ERROR_INVALID_FILENAME,
+ g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_FILENAME,
_("Invalid filename %s"), display_name);
return NULL;
}
new_file = g_file_get_child (file, basename);
g_free (basename);
-
+
return new_file;
}
@@ -412,13 +423,186 @@
GCancellable *cancellable,
GError **error)
{
- g_set_error_literal (error, G_IO_ERROR,
- G_IO_ERROR_NOT_SUPPORTED,
+ g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
_("Operation not supported"));
return NULL;
}
+static time_t
+mktime_utc (SYSTEMTIME *t)
+{
+ time_t retval;
+
+ static const gint days_before[] =
+ {
+ 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334
+ };
+
+ if (t->wMonth < 1 || t->wMonth > 12)
+ return (time_t) -1;
+
+ retval = (t->wYear - 1970) * 365;
+ retval += (t->wYear - 1968) / 4;
+ retval += days_before[t->wMonth-1] + t->wDay - 1;
+
+ if (t->wYear % 4 == 0 && t->wMonth < 3)
+ retval -= 1;
+
+ retval = ((((retval * 24) + t->wHour) * 60) + t->wMinute) * 60 + t->wSecond;
+
+ return retval;
+}
+
+static GFileInfo *
+g_winhttp_file_query_info (GFile *file,
+ const char *attributes,
+ GFileQueryInfoFlags flags,
+ GCancellable *cancellable,
+ GError **error)
+{
+ GWinHttpFile *winhttp_file = G_WINHTTP_FILE (file);
+ HINTERNET connection, request;
+ const wchar_t *accept_types[] =
+ {
+ L"*/*",
+ NULL,
+ };
+ GFileInfo *info;
+ GFileAttributeMatcher *matcher;
+ char *basename;
+ wchar_t *content_length;
+ wchar_t *content_type;
+ SYSTEMTIME last_modified;
+ DWORD last_modified_len;
+
+ connection = G_WINHTTP_VFS_GET_CLASS (winhttp_file->vfs)->pWinHttpConnect
+ (G_WINHTTP_VFS (winhttp_file->vfs)->session,
+ winhttp_file->url.lpszHostName,
+ winhttp_file->url.nPort,
+ 0);
+
+ if (connection == NULL)
+ {
+ _g_winhttp_set_error (error, GetLastError (), "HTTP connection");
+
+ return NULL;
+ }
+
+ request = G_WINHTTP_VFS_GET_CLASS (winhttp_file->vfs)->pWinHttpOpenRequest
+ (connection,
+ L"HEAD",
+ winhttp_file->url.lpszUrlPath,
+ NULL,
+ WINHTTP_NO_REFERER,
+ accept_types,
+ winhttp_file->url.nScheme == INTERNET_SCHEME_HTTPS ? WINHTTP_FLAG_SECURE : 0);
+
+ if (request == NULL)
+ {
+ _g_winhttp_set_error (error, GetLastError (), "HEAD request");
+
+ return NULL;
+ }
+
+ if (!G_WINHTTP_VFS_GET_CLASS (winhttp_file->vfs)->pWinHttpSendRequest
+ (request,
+ NULL, 0,
+ NULL, 0,
+ 0,
+ 0))
+ {
+ _g_winhttp_set_error (error, GetLastError (), "HEAD request");
+
+ return NULL;
+ }
+
+ if (!_g_winhttp_response (winhttp_file->vfs, request, error, "HEAD request"))
+ return NULL;
+
+ matcher = g_file_attribute_matcher_new (attributes);
+ info = g_file_info_new ();
+ g_file_info_set_attribute_mask (info, matcher);
+
+ basename = g_winhttp_file_get_basename (file);
+ g_file_info_set_name (info, basename);
+ g_free (basename);
+
+ content_length = NULL;
+ if (_g_winhttp_query_header (winhttp_file->vfs,
+ request,
+ "HEAD request",
+ WINHTTP_QUERY_CONTENT_LENGTH,
+ &content_length,
+ NULL))
+ {
+ gint64 cl;
+ int n;
+
+ if (swscanf (content_length, L"%I64d%n", &cl, &n) == 1 &&
+ n == wcslen (content_length))
+ g_file_info_set_size (info, cl);
+
+ g_free (content_length);
+ }
+
+ if (matcher == NULL)
+ return info;
+
+ content_type = NULL;
+ if (_g_winhttp_query_header (winhttp_file->vfs,
+ request,
+ "HEAD request",
+ WINHTTP_QUERY_CONTENT_TYPE,
+ &content_type,
+ NULL))
+ {
+ char *ct = g_utf16_to_utf8 (content_type, -1, NULL, NULL, NULL);
+
+ if (ct != NULL)
+ {
+ char *p = strchr (ct, ';');
+
+ if (p != NULL)
+ {
+ char *tmp = g_strndup (ct, p - ct);
+
+ g_file_info_set_content_type (info, tmp);
+ g_free (tmp);
+ }
+ else
+ g_file_info_set_content_type (info, ct);
+ }
+
+ g_free (ct);
+ }
+
+ last_modified_len = sizeof (last_modified);
+ if (G_WINHTTP_VFS_GET_CLASS (winhttp_file->vfs)->pWinHttpQueryHeaders
+ (request,
+ WINHTTP_QUERY_LAST_MODIFIED | WINHTTP_QUERY_FLAG_SYSTEMTIME,
+ NULL,
+ &last_modified,
+ &last_modified_len,
+ NULL) &&
+ last_modified_len == sizeof (last_modified) &&
+ /* Don't bother comparing to the exact Y2038 moment */
+ last_modified.wYear >= 1970 &&
+ last_modified.wYear < 2038)
+ {
+ GTimeVal tv;
+
+ tv.tv_sec = mktime_utc (&last_modified);
+ tv.tv_usec = last_modified.wMilliseconds * 1000;
+
+ g_file_info_set_modification_time (info, &tv);
+ }
+
+ g_file_attribute_matcher_unref (matcher);
+
+ return info;
+}
+
static GFileInputStream *
g_winhttp_file_read (GFile *file,
GCancellable *cancellable,
@@ -440,12 +624,7 @@
if (connection == NULL)
{
- char *emsg = _g_winhttp_error_message (GetLastError ());
-
- g_set_error (error, G_IO_ERROR,
- G_IO_ERROR_FAILED,
- "%s", emsg);
- g_free (emsg);
+ _g_winhttp_set_error (error, GetLastError (), "HTTP connection");
return NULL;
}
@@ -461,12 +640,7 @@
if (request == NULL)
{
- char *emsg = _g_winhttp_error_message (GetLastError ());
-
- g_set_error (error, G_IO_ERROR,
- G_IO_ERROR_FAILED,
- "%s", emsg);
- g_free (emsg);
+ _g_winhttp_set_error (error, GetLastError (), "GET request");
return NULL;
}
@@ -481,7 +655,7 @@
GError **error)
{
GWinHttpFile *winhttp_file = G_WINHTTP_FILE (file);
- HINTERNET connection, request;
+ HINTERNET connection;
connection = G_WINHTTP_VFS_GET_CLASS (winhttp_file->vfs)->pWinHttpConnect
(G_WINHTTP_VFS (winhttp_file->vfs)->session,
@@ -491,12 +665,7 @@
if (connection == NULL)
{
- char *emsg = _g_winhttp_error_message (GetLastError ());
-
- g_set_error (error, G_IO_ERROR,
- G_IO_ERROR_FAILED,
- "%s", emsg);
- g_free (emsg);
+ _g_winhttp_set_error (error, GetLastError (), "HTTP connection");
return NULL;
}
@@ -550,7 +719,8 @@
GError **error)
{
/* Fall back to default copy?? */
- g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, "Copy not supported");
+ g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
+ "Copy not supported");
return FALSE;
}
@@ -590,6 +760,7 @@
iface->resolve_relative_path = g_winhttp_file_resolve_relative_path;
iface->get_child_for_display_name = g_winhttp_file_get_child_for_display_name;
iface->set_display_name = g_winhttp_file_set_display_name;
+ iface->query_info = g_winhttp_file_query_info;
iface->read_fn = g_winhttp_file_read;
iface->create = g_winhttp_file_create;
#if 0
Modified: trunk/gio/win32/gwinhttpfileinputstream.c
==============================================================================
--- trunk/gio/win32/gwinhttpfileinputstream.c (original)
+++ trunk/gio/win32/gwinhttpfileinputstream.c Wed Aug 13 19:39:49 2008
@@ -1,5 +1,5 @@
/* GIO - GLib Input, Output and Streaming Library
- *
+ *
* Copyright (C) 2006-2007 Red Hat, Inc.
* Copyright (C) 2008 Novell, Inc.
*
@@ -61,7 +61,7 @@
g_winhttp_file_input_stream_finalize (GObject *object)
{
GWinHttpFileInputStream *winhttp_stream;
-
+
winhttp_stream = G_WINHTTP_FILE_INPUT_STREAM (object);
if (winhttp_stream->request != NULL)
@@ -77,7 +77,7 @@
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
GInputStreamClass *stream_class = G_INPUT_STREAM_CLASS (klass);
-
+
gobject_class->finalize = g_winhttp_file_input_stream_finalize;
stream_class->read_fn = g_winhttp_file_input_stream_read;
@@ -90,10 +90,10 @@
/**
* g_winhttp_file_input_stream_new:
- * @file: the GWinHttpFile being read
+ * @file: the GWinHttpFile being read
* @connection: handle to the HTTP connection, as from WinHttpConnect()
* @request: handle to the HTTP request, as from WinHttpOpenRequest
- *
+ *
* Returns: #GFileInputStream for the given request
**/
GFileInputStream *
@@ -109,7 +109,7 @@
stream->request_sent = FALSE;
stream->connection = connection;
stream->request = request;
-
+
return G_FILE_INPUT_STREAM (stream);
}
@@ -132,39 +132,27 @@
0,
0))
{
- char *emsg = _g_winhttp_error_message (GetLastError ());
-
- g_set_error (error, G_IO_ERROR,
- G_IO_ERROR_FAILED,
- "%s", emsg);
- g_free (emsg);
-
- return -1;
- }
-
- if (!G_WINHTTP_VFS_GET_CLASS (winhttp_stream->file->vfs)->pWinHttpReceiveResponse
- (winhttp_stream->request, NULL))
- {
- char *emsg = _g_winhttp_error_message (GetLastError ());
- g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
- "%s", emsg);
- g_free (emsg);
+ _g_winhttp_set_error (error, GetLastError (), "GET request");
return -1;
}
+
+ if (!_g_winhttp_response (winhttp_stream->file->vfs,
+ winhttp_stream->request,
+ error,
+ "GET request"))
+ return -1;
+
winhttp_stream->request_sent = TRUE;
}
-
+
if (!G_WINHTTP_VFS_GET_CLASS (winhttp_stream->file->vfs)->pWinHttpReadData
(winhttp_stream->request, buffer, count, &bytes_read))
{
- char *emsg = _g_winhttp_error_message (GetLastError ());
- g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
- "%s", emsg);
- g_free (emsg);
+ _g_winhttp_set_error (error, GetLastError (), "GET request");
return -1;
}
-
+
return bytes_read;
}
Modified: trunk/gio/win32/gwinhttpfileoutputstream.c
==============================================================================
--- trunk/gio/win32/gwinhttpfileoutputstream.c (original)
+++ trunk/gio/win32/gwinhttpfileoutputstream.c Wed Aug 13 19:39:49 2008
@@ -1,5 +1,5 @@
/* GIO - GLib Input, Output and Streaming Library
- *
+ *
* Copyright (C) 2006-2007 Red Hat, Inc.
* Copyright (C) 2008 Novell, Inc.
*
@@ -60,7 +60,7 @@
g_winhttp_file_output_stream_finalize (GObject *object)
{
GWinHttpFileOutputStream *winhttp_stream;
-
+
winhttp_stream = G_WINHTTP_FILE_OUTPUT_STREAM (object);
if (winhttp_stream->connection != NULL)
@@ -74,7 +74,7 @@
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
GOutputStreamClass *stream_class = G_OUTPUT_STREAM_CLASS (klass);
-
+
gobject_class->finalize = g_winhttp_file_output_stream_finalize;
stream_class->write_fn = g_winhttp_file_output_stream_write;
@@ -87,10 +87,10 @@
/**
* g_winhttp_file_output_stream_new:
- * @file: the GWinHttpFile being read
+ * @file: the GWinHttpFile being read
* @connection: handle to the HTTP connection, as from WinHttpConnect()
* @request: handle to the HTTP request, as from WinHttpOpenRequest
- *
+ *
* Returns: #GFileOutputStream for the given request
**/
GFileOutputStream *
@@ -132,12 +132,7 @@
if (request == NULL)
{
- char *emsg = _g_winhttp_error_message (GetLastError ());
-
- g_set_error (error, G_IO_ERROR,
- G_IO_ERROR_FAILED,
- "%s", emsg);
- g_free (emsg);
+ _g_winhttp_set_error (error, GetLastError (), "PUT request");
return -1;
}
@@ -154,47 +149,35 @@
count,
0))
{
- char *emsg = _g_winhttp_error_message (GetLastError ());
-
- g_set_error (error, G_IO_ERROR,
- G_IO_ERROR_FAILED,
- "%s", emsg);
- g_free (emsg);
-
+ _g_winhttp_set_error (error, GetLastError (), "PUT request");
+
G_WINHTTP_VFS_GET_CLASS (winhttp_stream->file->vfs)->pWinHttpCloseHandle (request);
g_free (wheaders);
return -1;
}
-
+
g_free (wheaders);
if (!G_WINHTTP_VFS_GET_CLASS (winhttp_stream->file->vfs)->pWinHttpWriteData
(request, buffer, count, &bytes_written))
{
- char *emsg = _g_winhttp_error_message (GetLastError ());
- g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
- "%s",
- emsg);
- g_free (emsg);
+ _g_winhttp_set_error (error, GetLastError (), "PUT request");
G_WINHTTP_VFS_GET_CLASS (winhttp_stream->file->vfs)->pWinHttpCloseHandle (request);
return -1;
}
-
+
winhttp_stream->offset += bytes_written;
- if (!G_WINHTTP_VFS_GET_CLASS (winhttp_stream->file->vfs)->pWinHttpReceiveResponse
- (request, NULL))
+ if (!_g_winhttp_response (winhttp_stream->file->vfs,
+ request,
+ error,
+ "PUT request"))
{
- char *emsg = _g_winhttp_error_message (GetLastError ());
- g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
- "%s",
- emsg);
- g_free (emsg);
-
G_WINHTTP_VFS_GET_CLASS (winhttp_stream->file->vfs)->pWinHttpCloseHandle (request);
+
return -1;
}
Modified: trunk/gio/win32/gwinhttpvfs.c
==============================================================================
--- trunk/gio/win32/gwinhttpvfs.c (original)
+++ trunk/gio/win32/gwinhttpvfs.c Wed Aug 13 19:39:49 2008
@@ -1,5 +1,5 @@
/* GIO - GLib Input, Output and Streaming Library
- *
+ *
* Copyright (C) 2006-2007 Red Hat, Inc.
* Copyright (C) 2008 Novell, Inc.
*
@@ -24,6 +24,9 @@
#include "config.h"
+#include <wchar.h>
+
+#include "gioerror.h"
#include "giomodule.h"
#include "gvfs.h"
@@ -69,7 +72,7 @@
if (!wagent)
wagent = g_utf8_to_utf16 ("GWinHttpVfs", -1, NULL, NULL, NULL);
-
+
vfs->session = (G_WINHTTP_VFS_GET_CLASS (vfs)->pWinHttpOpen)
(wagent,
WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,
@@ -142,7 +145,7 @@
}
retval[n] = NULL;
-
+
return retval;
}
@@ -151,7 +154,7 @@
const char *parse_name)
{
GWinHttpVfs *winhttp_vfs = G_WINHTTP_VFS (vfs);
-
+
g_return_val_if_fail (G_IS_VFS (vfs), NULL);
g_return_val_if_fail (parse_name != NULL, NULL);
@@ -177,7 +180,7 @@
GObjectClass *object_class;
GVfsClass *vfs_class;
HMODULE winhttp;
-
+
object_class = (GObjectClass *) class;
object_class->finalize = g_winhttp_vfs_finalize;
@@ -266,9 +269,154 @@
CASE (UNRECOGNIZED_SCHEME);
#undef CASE
default:
- return g_strdup_printf ("WinHttp error %ld", error_code);
+ return g_strdup_printf ("WinHttp error %ld", error_code);
}
}
else
return g_win32_error_message (error_code);
}
+
+void
+_g_winhttp_set_error (GError **error,
+ DWORD error_code,
+ const char *what)
+{
+ char *emsg = _g_winhttp_error_message (error_code);
+
+ g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
+ "%s failed: %s", what, emsg);
+ g_free (emsg);
+}
+
+gboolean
+_g_winhttp_response (GWinHttpVfs *vfs,
+ HINTERNET request,
+ GError **error,
+ const char *what)
+{
+ wchar_t *status_code;
+ DWORD status_code_len;
+
+ if (!G_WINHTTP_VFS_GET_CLASS (vfs)->pWinHttpReceiveResponse (request, NULL))
+ {
+ _g_winhttp_set_error (error, GetLastError (), what);
+
+ return FALSE;
+ }
+
+ status_code_len = 0;
+ if (!G_WINHTTP_VFS_GET_CLASS (vfs)->pWinHttpQueryHeaders
+ (request,
+ WINHTTP_QUERY_STATUS_CODE,
+ NULL,
+ NULL,
+ &status_code_len,
+ NULL) &&
+ GetLastError () != ERROR_INSUFFICIENT_BUFFER)
+ {
+ _g_winhttp_set_error (error, GetLastError (), what);
+
+ return FALSE;
+ }
+
+ status_code = g_malloc (status_code_len);
+
+ if (!G_WINHTTP_VFS_GET_CLASS (vfs)->pWinHttpQueryHeaders
+ (request,
+ WINHTTP_QUERY_STATUS_CODE,
+ NULL,
+ status_code,
+ &status_code_len,
+ NULL))
+ {
+ _g_winhttp_set_error (error, GetLastError (), what);
+ g_free (status_code);
+
+ return FALSE;
+ }
+
+ if (status_code[0] != L'2')
+ {
+ wchar_t *status_text = NULL;
+ DWORD status_text_len;
+
+ if (!G_WINHTTP_VFS_GET_CLASS (vfs)->pWinHttpQueryHeaders
+ (request,
+ WINHTTP_QUERY_STATUS_TEXT,
+ NULL,
+ NULL,
+ &status_text_len,
+ NULL) &&
+ GetLastError () == ERROR_INSUFFICIENT_BUFFER)
+ {
+ status_text = g_malloc (status_text_len);
+
+ if (!G_WINHTTP_VFS_GET_CLASS (vfs)->pWinHttpQueryHeaders
+ (request,
+ WINHTTP_QUERY_STATUS_TEXT,
+ NULL,
+ status_text,
+ &status_text_len,
+ NULL))
+ {
+ g_free (status_text);
+ status_text = NULL;
+ }
+ }
+
+ g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
+ "%s failed: %S %S",
+ what, status_code, status_text ? status_text : L"");
+ g_free (status_code);
+ g_free (status_text);
+
+ return FALSE;
+ }
+
+ g_free (status_code);
+
+ return TRUE;
+}
+
+gboolean
+_g_winhttp_query_header (GWinHttpVfs *vfs,
+ HINTERNET request,
+ const char *request_description,
+ DWORD which_header,
+ wchar_t **header,
+ GError **error)
+{
+ DWORD header_len = 0;
+
+ if (!G_WINHTTP_VFS_GET_CLASS (vfs)->pWinHttpQueryHeaders
+ (request,
+ which_header,
+ NULL,
+ NULL,
+ &header_len,
+ NULL) &&
+ GetLastError () != ERROR_INSUFFICIENT_BUFFER)
+ {
+ _g_winhttp_set_error (error, GetLastError (), request_description);
+
+ return FALSE;
+ }
+
+ *header = g_malloc (header_len);
+ if (!G_WINHTTP_VFS_GET_CLASS (vfs)->pWinHttpQueryHeaders
+ (request,
+ which_header,
+ NULL,
+ *header,
+ &header_len,
+ NULL))
+ {
+ _g_winhttp_set_error (error, GetLastError (), request_description);
+ g_free (*header);
+ *header = NULL;
+
+ return FALSE;
+ }
+
+ return TRUE;
+}
Modified: trunk/gio/win32/gwinhttpvfs.h
==============================================================================
--- trunk/gio/win32/gwinhttpvfs.h (original)
+++ trunk/gio/win32/gwinhttpvfs.h Wed Aug 13 19:39:49 2008
@@ -1,6 +1,6 @@
/* GIO - GLib Input, Output and Streaming Library
- *
- * Copyright (C) 2006-2007 Red Hat, Inc.
+ *
+ * Copyright (C) 2006-2007 Red Hat, Inc.
* Copyright (C) 2008 Novell, Inc.
*
* This library is free software; you can redistribute it and/or
@@ -83,6 +83,22 @@
char *_g_winhttp_error_message (DWORD error_code);
+void _g_winhttp_set_error (GError **error,
+ DWORD error_code,
+ const char *what);
+
+gboolean _g_winhttp_response (GWinHttpVfs *vfs,
+ HINTERNET request,
+ GError **error,
+ const char *what);
+
+gboolean _g_winhttp_query_header (GWinHttpVfs *vfs,
+ HINTERNET request,
+ const char *request_description,
+ DWORD which_header,
+ wchar_t **header,
+ GError **error);
+
G_END_DECLS
#endif /* __G_WINHTTP_VFS_H__ */
Modified: trunk/gio/win32/winhttp.h
==============================================================================
--- trunk/gio/win32/winhttp.h (original)
+++ trunk/gio/win32/winhttp.h Wed Aug 13 19:39:49 2008
@@ -229,6 +229,18 @@
#define ICU_ESCAPE 0x80000000
#define ICU_DECODE 0x10000000
+/* A few constants I couldn't find publicly documented, so I looked up
+ * their value from the Windows SDK <winhttp.h>. Presumably this falls
+ * under fair use.
+ */
+#define WINHTTP_QUERY_CONTENT_LENGTH 5
+#define WINHTTP_QUERY_CONTENT_TYPE 1
+#define WINHTTP_QUERY_LAST_MODIFIED 11
+#define WINHTTP_QUERY_STATUS_CODE 19
+#define WINHTTP_QUERY_STATUS_TEXT 20
+
+#define WINHTTP_QUERY_FLAG_SYSTEMTIME 0x40000000
+
#ifdef __cplusplus
}
#endif
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]