return ret;
}
-/* Does not allocate the 'handle' memory. */
+/* Do not allocate the 'handle' memory. */
static void
-http_file_handle_new (HttpFileHandle *handle,
- GnomeVFSSocketBuffer *socket_buffer,
- GnomeVFSURI *uri)
+http_file_handle_init (HttpFileHandle *handle,
+ GnomeVFSSocketBuffer *socket_buffer,
+ GnomeVFSURI *uri)
{
memset (handle, 0, sizeof (*handle));
handle->file_info->name = gnome_vfs_uri_extract_short_name (uri);
}
+static HttpFileHandle *
+http_file_handle_alloc (void)
+{
+ return g_new0 (HttpFileHandle, 1);
+}
+
+static HttpFileHandle *
+http_file_handle_new (GnomeVFSSocketBuffer *socket_buffer,
+ GnomeVFSURI *uri)
+{
+ HttpFileHandle *result;
+
+ result = http_file_handle_alloc ();
+ http_file_handle_init (result, socket_buffer, uri);
+
+ return result;
+}
+
/* Does not free the 'handle' memory. */
static void
-http_file_handle_destroy (HttpFileHandle *handle)
+http_file_handle_clear (HttpFileHandle *handle)
{
- if (handle == NULL) {
+ if (handle == NULL || handle->uri == NULL) {
return;
}
g_list_foreach(handle->files, (GFunc)gnome_vfs_file_info_unref, NULL);
g_list_free(handle->files);
+
+ /* Structure is now fully cleared: */
+ memset (handle, 0, sizeof (*handle));
+}
+
+static void
+http_file_handle_destroy (HttpFileHandle *handle)
+{
+ if (handle == NULL) {
+ return;
+ }
+
+ http_file_handle_clear (handle);
+
+ g_free (handle);
}
/* The following comes from GNU Wget with minor changes by myself.
/* rename this function? */
static GnomeVFSResult
-create_handle (GnomeVFSURI *uri,
- GnomeVFSSocketBuffer *socket_buffer,
- GnomeVFSContext *context,
- /* OUT */ HttpFileHandle *handle)
+init_handle (GnomeVFSURI *uri,
+ GnomeVFSSocketBuffer *socket_buffer,
+ GnomeVFSContext *context,
+ /* OUT */ HttpFileHandle *handle)
{
GString *header_string;
GnomeVFSResult result;
g_return_val_if_fail (handle != NULL, GNOME_VFS_ERROR_INTERNAL);
- http_file_handle_new (handle, socket_buffer, uri);
+ http_file_handle_init (handle, socket_buffer, uri);
header_string = g_string_new (NULL);
- ANALYZE_HTTP ("==> +create_handle");
+ ANALYZE_HTTP ("==> +init_handle");
/* This is the status report string, which is the first header. */
result = get_header (socket_buffer, header_string);
handle->server_status = server_status;
- ANALYZE_HTTP ("==> +create_handle: fetching headers");
+ ANALYZE_HTTP ("==> +init_handle: fetching headers");
/* Header fetching loop. */
for (;;) {
invoke_callback_headers_received (handle);
- ANALYZE_HTTP ("==> -create_handle: fetching headers");
+ ANALYZE_HTTP ("==> -init_handle: fetching headers");
if (result != GNOME_VFS_OK) {
goto error;
error:
g_string_free (header_string, TRUE);
- ANALYZE_HTTP ("==> -create_handle");
+ ANALYZE_HTTP ("==> -init_handle");
return result;
}
return result;
}
+/* Do not allocate the 'handle' memory. */
static GnomeVFSResult
-make_request (HttpFileHandle *handle,
+init_request (HttpFileHandle *handle,
GnomeVFSURI *uri,
const gchar *method,
GByteArray *data,
gboolean proxy_connect;
char *authn_header_request;
char *authn_header_proxy;
- gboolean handle_valid = FALSE;
g_return_val_if_fail (handle != NULL, GNOME_VFS_ERROR_INTERNAL);
- ANALYZE_HTTP ("==> +make_request");
+ ANALYZE_HTTP ("==> +init_request");
request = NULL;
proxy_connect = FALSE;
}
/* Read the headers and create our internal HTTP file handle. */
- result = create_handle (uri, socket_buffer, context, handle);
- handle_valid = TRUE;
+ result = init_handle (uri, socket_buffer, context, handle);
if (result == GNOME_VFS_OK) {
socket_buffer = NULL;
} else {
break;
}
- http_file_handle_destroy (handle);
- handle_valid = FALSE;
+ http_file_handle_clear (handle);
}
g_free (authn_header_request);
g_free (authn_header_proxy);
- if (result != GNOME_VFS_OK && handle_valid) {
- http_file_handle_destroy (handle);
- handle_valid = FALSE;
+ if (result != GNOME_VFS_OK) {
+ http_file_handle_clear (handle);
}
if (request != NULL) {
gnome_vfs_socket_buffer_destroy (socket_buffer, TRUE);
}
- ANALYZE_HTTP ("==> -make_request");
+ ANALYZE_HTTP ("==> -init_request");
+ return result;
+}
+
+static GnomeVFSResult
+make_request (HttpFileHandle **handle_return,
+ GnomeVFSURI *uri,
+ const gchar *method,
+ GByteArray *data,
+ gchar *extra_headers,
+ GnomeVFSContext *context)
+{
+ GnomeVFSResult result;
+
+ g_return_val_if_fail (handle_return != NULL, GNOME_VFS_ERROR_INTERNAL);
+
+ *handle_return = http_file_handle_alloc ();
+ result = init_request (*handle_return, uri, method, data, extra_headers, context);
+ if (result != GNOME_VFS_OK) {
+ http_file_handle_destroy (*handle_return);
+ *handle_return = NULL;
+ }
+
return result;
}
static void
-http_handle_close (HttpFileHandle *handle,
+http_handle_clear (HttpFileHandle *handle,
GnomeVFSContext *context)
{
- ANALYZE_HTTP ("==> +http_handle_close");
+ ANALYZE_HTTP ("==> +http_handle_clear");
if (handle != NULL) {
if (handle->socket_buffer) {
handle->socket_buffer = NULL;
}
- http_file_handle_destroy (handle);
+ http_file_handle_clear (handle);
}
- ANALYZE_HTTP ("==> -http_handle_close");
+ ANALYZE_HTTP ("==> -http_handle_clear");
+}
+
+static void
+http_handle_close (HttpFileHandle *handle,
+ GnomeVFSContext *context)
+{
+ http_handle_clear (handle, context);
+
+ http_file_handle_destroy (handle);
}
static GnomeVFSResult
ANALYZE_HTTP ("==> +do_open");
DEBUG_HTTP (("+Open URI: '%s' mode:'%c'", gnome_vfs_uri_to_string(uri, 0),
mode & GNOME_VFS_OPEN_READ ? 'R' : 'W'));
-
- handle = g_new (HttpFileHandle, 1);
+
if (mode & GNOME_VFS_OPEN_READ) {
- result = make_request (handle, uri, "GET", NULL, NULL,
+ result = make_request (&handle, uri, "GET", NULL, NULL,
context);
} else {
- http_file_handle_new(handle, NULL, uri); /* shrug */
+ handle = http_file_handle_new(NULL, uri); /* shrug */
}
if (result == GNOME_VFS_OK) {
*method_handle = (GnomeVFSMethodHandle *) handle;
ANALYZE_HTTP ("==> Checking to see if file exists");
- handle = g_new (HttpFileHandle, 1);
- result = make_request (handle, uri, "HEAD", NULL, NULL,
+ result = make_request (&handle, uri, "HEAD", NULL, NULL,
context);
http_handle_close (handle, context);
- g_free (handle);
if (result != GNOME_VFS_OK &&
result != GNOME_VFS_ERROR_NOT_FOUND) {
ANALYZE_HTTP ("==> Creating initial file");
- handle = g_new (HttpFileHandle, 1);
- result = make_request (handle, uri, "PUT", bytes, NULL, context);
+ result = make_request (&handle, uri, "PUT", bytes, NULL, context);
http_handle_close(handle, context);
- g_free (handle);
if (result != GNOME_VFS_OK) {
/* the PUT failed */
http_cache_invalidate_uri (uri);
ANALYZE_HTTP ("==> doing PUT");
- new_handle = g_new (HttpFileHandle, 1);
- result = make_request (new_handle, uri, "PUT", bytes,
+ result = make_request (&new_handle, uri, "PUT", bytes,
extraheader, context);
g_free (extraheader);
http_handle_close (new_handle, context);
- g_free (new_handle);
} else {
result = GNOME_VFS_OK;
}
-
+
http_handle_close (old_handle, context);
- g_free (old_handle);
DEBUG_HTTP (("-Close (%d)", result));
ANALYZE_HTTP ("==> -do_close");
if (1
&& handle->offset > handle->socket_buffer_offset
&& handle->offset <= handle->socket_buffer_offset+MAX_BUFFER_SEEK_SKIP_READ) {
-static char drop_buffer[0x1000];
-GnomeVFSFileSize bytes, bytes_read;
-GnomeVFSResult result;
+ static char drop_buffer[0x1000];
+ GnomeVFSFileSize bytes, bytes_read;
+ GnomeVFSResult result;
while ((bytes=MIN(sizeof(drop_buffer), handle->offset - handle->socket_buffer_offset))) {
result = gnome_vfs_socket_buffer_read (handle->socket_buffer, drop_buffer,
offset_save = handle->offset;
gnome_vfs_uri_ref(uri);
- http_handle_close (handle, context);
- extra_headers = g_strdup_printf("Range: bytes=%" G_GINT64_FORMAT "-\r\n",(gint64)handle->offset);
- result = make_request (handle, uri, "GET", NULL, extra_headers,
+ http_handle_clear (handle, context);
+ /* 'handle->offset' is already destroyed here: */
+ extra_headers = g_strdup_printf("Range: bytes=%" G_GINT64_FORMAT "-\r\n",(gint64)offset_save);
+ result = init_request (handle, uri, "GET", NULL, extra_headers,
context);
g_free (extra_headers);
gnome_vfs_uri_unref(uri);
static GnomeVFSResult
-make_propfind_request (HttpFileHandle *handle,
+make_propfind_request (HttpFileHandle **handle_return,
GnomeVFSURI *uri,
gint depth,
GnomeVFSContext *context)
xmlNodePtr cur = NULL;
char *extraheaders = g_strdup_printf("Depth: %d\r\n", depth);
gboolean found_root_node_props;
- gboolean handle_valid = FALSE;
GByteArray *request = g_byte_array_new();
char *request_str = "<?xml version=\"1.0\" encoding=\"utf-8\" ?>"
http_cache_invalidate_uri_and_children (uri);
}
- result = make_request (handle, uri, "PROPFIND", request,
+ result = make_request (handle_return, uri, "PROPFIND", request,
extraheaders, context);
- if (result == GNOME_VFS_OK)
- handle_valid = TRUE;
/* FIXME bugzilla.gnome.org 43834: It looks like some http
* servers (eg, www.yahoo.com) treat PROPFIND as a GET and
* redirects or any other legal response. This case probably
* needs to be made more robust.
*/
- if (result == GNOME_VFS_OK && handle->server_status != 207) { /* Multi-Status */
- DEBUG_HTTP (("HTTP server returned an invalid PROPFIND response: %d", handle->server_status));
+ if (result == GNOME_VFS_OK && (*handle_return)->server_status != 207) { /* Multi-Status */
+ DEBUG_HTTP (("HTTP server returned an invalid PROPFIND response: %d", (*handle_return)->server_status));
result = GNOME_VFS_ERROR_NOT_SUPPORTED;
}
if (result == GNOME_VFS_OK) {
do {
- result = do_read (NULL, (GnomeVFSMethodHandle *) handle,
+ result = do_read (NULL, (GnomeVFSMethodHandle *) *handle_return,
buffer, num_bytes, &bytes_read, context);
if (result != GNOME_VFS_OK ) {
process_propfind_response (cur->xmlChildrenNode, uri);
if (file_info->name != NULL) {
- handle->files = g_list_append (handle->files, file_info);
+ (*handle_return)->files = g_list_append ((*handle_return)->files, file_info);
} else {
/* This response refers to the root node */
- /* Abandon the old information that came from create_handle*/
+ /* Abandon the old information that came from init_handle */
- file_info->name = handle->file_info->name;
- handle->file_info->name = NULL;
- gnome_vfs_file_info_unref (handle->file_info);
- handle->file_info = file_info;
+ file_info->name = (*handle_return)->file_info->name;
+ (*handle_return)->file_info->name = NULL;
+ gnome_vfs_file_info_unref ((*handle_return)->file_info);
+ (*handle_return)->file_info = file_info;
found_root_node_props = TRUE;
}
*/
if (depth == 0) {
- http_cache_add_uri (uri, handle->file_info, TRUE);
+ http_cache_add_uri (uri, (*handle_return)->file_info, TRUE);
} else {
- http_cache_add_uri_and_children (uri, handle->file_info, handle->files);
+ http_cache_add_uri_and_children (uri, (*handle_return)->file_info, (*handle_return)->files);
}
cleanup:
g_free(extraheaders);
xmlFreeParserCtxt(parserContext);
- if (result != GNOME_VFS_OK && handle_valid) {
- http_handle_close (handle, context);
+ if (result != GNOME_VFS_OK) {
+ http_handle_close (*handle_return, context);
+ *handle_return = NULL;
}
ANALYZE_HTTP ("==> -make_propfind_request");
file_info_cached = http_cache_check_directory_uri (uri, &child_file_info_cached_list);
if (file_info_cached) {
- handle = g_new (HttpFileHandle, 1);
- http_file_handle_new (handle, NULL, uri);
+ handle = http_file_handle_new (NULL, uri);
gnome_vfs_file_info_unref (handle->file_info);
handle->file_info = file_info_cached;
handle->files = child_file_info_cached_list;
result = GNOME_VFS_OK;
} else {
- handle = g_new (HttpFileHandle, 1);
- result = make_propfind_request(handle, uri, 1, context);
+ result = make_propfind_request(&handle, uri, 1, context);
/* mfleming -- is this necessary? Most DAV server's I've seen don't have the horrible
* lack-of-trailing-/-is-a-301 problem for PROPFIND's
*/
&& handle->file_info->type != GNOME_VFS_FILE_TYPE_DIRECTORY) {
result = GNOME_VFS_ERROR_NOT_A_DIRECTORY;
http_handle_close (handle, context);
- g_free (handle);
handle = NULL;
}
}
handle = (HttpFileHandle *) method_handle;
http_handle_close(handle, context);
- g_free (handle);
DEBUG_HTTP (("-Close_Directory (0) handle:0x%08x", (unsigned int) method_handle));
* Start off by making a PROPFIND request. Fall back to a HEAD if it fails
*/
- handle = g_new (HttpFileHandle, 1);
- result = make_propfind_request (handle, uri, 0, context);
+ result = make_propfind_request (&handle, uri, 0, context);
/* Note that theoretically we could not bother with this request if we get a 404 back,
* but since some servers seem to return wierd things on PROPFIND (mostly 200 OK's...)
if (result == GNOME_VFS_OK) {
gnome_vfs_file_info_copy (file_info, handle->file_info);
http_handle_close (handle, context);
- g_free (handle);
handle = NULL;
} else {
- g_free (handle);
- handle = NULL;
g_assert (handle == NULL); /* Make sure we're not leaking some old one */
/* Lame buggy servers (eg: www.mozilla.org,
ANALYZE_HTTP ("==> do_get_file_info: do GET ");
- handle = g_new (HttpFileHandle, 1);
- result = make_request (handle, uri, "GET", NULL, NULL, context);
+ result = make_request (&handle, uri, "GET", NULL, NULL, context);
if (result == GNOME_VFS_OK) {
gnome_vfs_file_info_copy (file_info, handle->file_info);
http_cache_add_uri (uri, handle->file_info, FALSE);
http_handle_close (handle, context);
}
- g_free (handle);
- handle = NULL;
/* If we get a redirect, we should be
* basing the MIME type on the type of
* So we do a PROPFIND first to find out
*/
/* FIXME check cache here */
- handle = g_new (HttpFileHandle, 1);
- result = make_propfind_request(handle, uri, 0, context);
+ result = make_propfind_request(&handle, uri, 0, context);
if (result == GNOME_VFS_OK) {
result = GNOME_VFS_ERROR_FILE_EXISTS;
if (result == GNOME_VFS_ERROR_NOT_FOUND) {
http_cache_invalidate_uri_parent (uri);
- handle = g_new (HttpFileHandle, 1);
- result = make_request (handle, uri, "MKCOL", NULL, NULL, context);
+ result = make_request (&handle, uri, "MKCOL", NULL, NULL, context);
}
}
http_handle_close (handle, context);
- g_free (handle);
if (result == GNOME_VFS_ERROR_NOT_FOUND) {
result = resolve_409 (method, uri, context);
/* FIXME this should return GNOME_VFS_ERROR_DIRECTORY_NOT_EMPTY if the
* directory is not empty
*/
- handle = g_new (HttpFileHandle, 1);
- result = make_request (handle, uri, "DELETE", NULL, NULL,
+ result = make_request (&handle, uri, "DELETE", NULL, NULL,
context);
http_handle_close (handle, context);
- g_free (handle);
DEBUG_HTTP (("-Remove_Directory (%d)", result));
ANALYZE_HTTP ("==> -do_remove_directory");
destpath = gnome_vfs_uri_to_string (new_uri, GNOME_VFS_URI_HIDE_USER_NAME|GNOME_VFS_URI_HIDE_PASSWORD);
destheader = g_strdup_printf ("Destination: %s\r\nOverwrite: %c\r\n", destpath, force_replace ? 'T' : 'F' );
- handle = g_new (HttpFileHandle, 1);
- result = make_request (handle, old_uri, "MOVE", NULL, destheader, context);
+ result = make_request (&handle, old_uri, "MOVE", NULL, destheader, context);
http_handle_close (handle, context);
- g_free (handle);
handle = NULL;
if (result == GNOME_VFS_ERROR_NOT_FOUND) {