summaryrefslogtreecommitdiff
path: root/libsoup/soup-request-file.c
diff options
context:
space:
mode:
Diffstat (limited to 'libsoup/soup-request-file.c')
-rw-r--r--libsoup/soup-request-file.c394
1 files changed, 0 insertions, 394 deletions
diff --git a/libsoup/soup-request-file.c b/libsoup/soup-request-file.c
deleted file mode 100644
index 740b52a9..00000000
--- a/libsoup/soup-request-file.c
+++ /dev/null
@@ -1,394 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/*
- * soup-request-file.c: file: URI request object
- *
- * Copyright (C) 2009, 2010 Red Hat, Inc.
- * Copyright (C) 2010 Igalia, S.L.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 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
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <string.h>
-
-#include "soup-request-file.h"
-#include "soup.h"
-#include "soup-directory-input-stream.h"
-
-/**
- * SECTION:soup-request-file
- * @short_description: SoupRequest support for "file" and "resource" URIs
- *
- * #SoupRequestFile implements #SoupRequest for "file" and "resource"
- * URIs.
- */
-
-struct _SoupRequestFile {
- SoupRequest parent;
-};
-
-typedef struct {
- GFile *gfile;
-
- char *mime_type;
- goffset size;
-} SoupRequestFilePrivate;
-
-G_DEFINE_TYPE_WITH_PRIVATE (SoupRequestFile, soup_request_file, SOUP_TYPE_REQUEST)
-
-static void
-soup_request_file_init (SoupRequestFile *file)
-{
- SoupRequestFilePrivate *priv = soup_request_file_get_instance_private (file);
-
- priv->size = -1;
-}
-
-static void
-soup_request_file_finalize (GObject *object)
-{
- SoupRequestFile *file = SOUP_REQUEST_FILE (object);
- SoupRequestFilePrivate *priv = soup_request_file_get_instance_private (file);
-
- g_clear_object (&priv->gfile);
- g_free (priv->mime_type);
-
- G_OBJECT_CLASS (soup_request_file_parent_class)->finalize (object);
-}
-
-static gboolean
-soup_request_file_check_uri (SoupRequest *request,
- SoupURI *uri,
- GError **error)
-{
- /* "file:/foo" is not valid */
- if (!uri->host)
- return FALSE;
-
- /* but it must be "file:///..." or "file://localhost/..." */
- if (*uri->host &&
- g_ascii_strcasecmp (uri->host, "localhost") != 0)
- return FALSE;
- return TRUE;
-}
-
-#ifdef G_OS_WIN32
-static void
-windowsify_file_uri_path (char *path)
-{
- char *p, *slash;
-
- /* Copied from g_filename_from_uri(), which we can't use
- * directly because it rejects invalid URIs that we need to
- * keep.
- */
-
- /* Turn slashes into backslashes, because that's the canonical spelling */
- p = path;
- while ((slash = strchr (p, '/')) != NULL) {
- *slash = '\\';
- p = slash + 1;
- }
-
- /* Windows URIs with a drive letter can be like
- * "file://host/c:/foo" or "file://host/c|/foo" (some Netscape
- * versions). In those cases, start the filename from the
- * drive letter.
- */
- if (g_ascii_isalpha (path[1])) {
- if (path[2] == '|')
- path[2] = ':';
- if (path[2] == ':')
- memmove (path, path + 1, strlen (path));
- }
-}
-#endif
-
-/* Does not do I/O */
-static gboolean
-soup_request_file_ensure_file (SoupRequestFile *file,
- GCancellable *cancellable,
- GError **error)
-{
- SoupRequestFilePrivate *priv = soup_request_file_get_instance_private (file);
- SoupURI *uri;
- char *decoded_path;
-
- if (priv->gfile)
- return TRUE;
-
- uri = soup_request_get_uri (SOUP_REQUEST (file));
- decoded_path = soup_uri_decode (uri->path);
-
-#ifdef G_OS_WIN32
- windowsify_file_uri_path (decoded_path);
-#endif
-
- if (uri->scheme == SOUP_URI_SCHEME_RESOURCE) {
- char *uri_str;
-
- uri_str = g_strdup_printf ("resource://%s", decoded_path);
- priv->gfile = g_file_new_for_uri (uri_str);
- g_free (uri_str);
- } else
- priv->gfile = g_file_new_for_path (decoded_path);
-
- g_free (decoded_path);
- return TRUE;
-}
-
-static GInputStream *
-soup_request_file_send (SoupRequest *request,
- GCancellable *cancellable,
- GError **error)
-{
- SoupRequestFile *file = SOUP_REQUEST_FILE (request);
- SoupRequestFilePrivate *priv = soup_request_file_get_instance_private (file);
- GInputStream *stream;
- GError *my_error = NULL;
-
- if (!soup_request_file_ensure_file (file, cancellable, error))
- return NULL;
-
- stream = G_INPUT_STREAM (g_file_read (priv->gfile,
- cancellable, &my_error));
- if (stream == NULL) {
- if (g_error_matches (my_error, G_IO_ERROR, G_IO_ERROR_IS_DIRECTORY)) {
- GFileEnumerator *enumerator;
- g_clear_error (&my_error);
- enumerator = g_file_enumerate_children (priv->gfile,
- "*",
- G_FILE_QUERY_INFO_NONE,
- cancellable,
- error);
- if (enumerator) {
- stream = soup_directory_input_stream_new (enumerator,
- soup_request_get_uri (request));
- g_object_unref (enumerator);
- priv->mime_type = g_strdup ("text/html");
- }
- } else
- g_propagate_error (error, my_error);
- } else {
- GFileInfo *info = g_file_query_info (priv->gfile,
- G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE ","
- G_FILE_ATTRIBUTE_STANDARD_SIZE,
- 0, cancellable, NULL);
- if (info) {
- const char *content_type;
- priv->size = g_file_info_get_size (info);
- content_type = g_file_info_get_content_type (info);
-
- if (content_type)
- priv->mime_type = g_content_type_get_mime_type (content_type);
- g_object_unref (info);
- }
- }
-
- return stream;
-}
-
-static void
-on_enumerate_children_ready (GObject *source,
- GAsyncResult *result,
- gpointer user_data)
-{
- GTask *task = G_TASK (user_data);
- SoupRequestFile *file = SOUP_REQUEST_FILE (g_task_get_source_object (task));
- SoupRequestFilePrivate *priv = soup_request_file_get_instance_private (file);
- GFileEnumerator *enumerator;
- GError *error = NULL;
-
- enumerator = g_file_enumerate_children_finish (G_FILE (source), result, &error);
- if (enumerator == NULL) {
- g_task_return_error (task, error);
- } else {
- GInputStream *stream;
-
- stream = soup_directory_input_stream_new (enumerator,
- soup_request_get_uri (SOUP_REQUEST (file)));
- g_object_unref (enumerator);
- priv->mime_type = g_strdup ("text/html");
-
- g_task_return_pointer (task, stream, g_object_unref);
- }
-
- g_object_unref (task);
-}
-
-static void
-on_query_info_ready (GObject *source,
- GAsyncResult *result,
- gpointer user_data)
-{
- GTask *task = G_TASK (user_data);
- SoupRequestFile *file = SOUP_REQUEST_FILE (g_task_get_source_object (task));
- SoupRequestFilePrivate *priv = soup_request_file_get_instance_private (file);
- GInputStream *stream = G_INPUT_STREAM (g_task_get_task_data (task));
- GFileInfo *info;
- GError *error = NULL;
-
- info = g_file_query_info_finish (G_FILE (source), result, &error);
- if (info) {
- const char *content_type;
-
- priv->size = g_file_info_get_size (info);
- content_type = g_file_info_get_content_type (info);
-
- if (content_type)
- priv->mime_type = g_content_type_get_mime_type (content_type);
- g_object_unref (info);
- }
-
- g_task_return_pointer (task, g_object_ref (stream), g_object_unref);
- g_object_unref (task);
-}
-
-static void
-on_read_file_ready (GObject *source,
- GAsyncResult *result,
- gpointer user_data)
-{
- GTask *task = G_TASK (user_data);
- SoupRequestFile *file = SOUP_REQUEST_FILE (g_task_get_source_object (task));
- SoupRequestFilePrivate *priv = soup_request_file_get_instance_private (file);
- GInputStream *stream;
- GError *error = NULL;
-
- stream = G_INPUT_STREAM (g_file_read_finish (G_FILE (source), result, &error));
- if (stream == NULL) {
- if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_IS_DIRECTORY)) {
- g_file_enumerate_children_async (priv->gfile,
- "*",
- G_FILE_QUERY_INFO_NONE,
- G_PRIORITY_DEFAULT,
- g_task_get_cancellable (task),
- on_enumerate_children_ready,
- task);
- g_error_free (error);
- } else {
- g_task_return_error (task, error);
- g_object_unref (task);
- }
- } else {
- g_task_set_task_data (task, stream, g_object_unref);
- g_file_query_info_async (priv->gfile,
- G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE ","
- G_FILE_ATTRIBUTE_STANDARD_SIZE,
- 0,
- G_PRIORITY_DEFAULT,
- g_task_get_cancellable (task),
- on_query_info_ready,
- task);
- }
-}
-
-static void
-soup_request_file_send_async (SoupRequest *request,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data)
-{
- SoupRequestFile *file = SOUP_REQUEST_FILE (request);
- SoupRequestFilePrivate *priv = soup_request_file_get_instance_private (file);
- GTask *task;
- GError *error = NULL;
-
- task = g_task_new (request, cancellable, callback, user_data);
-
- if (!soup_request_file_ensure_file (file, cancellable, &error)) {
- g_task_return_error (task, error);
- g_object_unref (task);
- return;
- }
-
- g_file_read_async (priv->gfile,
- G_PRIORITY_DEFAULT,
- cancellable,
- on_read_file_ready,
- task);
-}
-
-static GInputStream *
-soup_request_file_send_finish (SoupRequest *request,
- GAsyncResult *result,
- GError **error)
-{
- g_return_val_if_fail (g_task_is_valid (result, request), NULL);
-
- return g_task_propagate_pointer (G_TASK (result), error);
-}
-
-static goffset
-soup_request_file_get_content_length (SoupRequest *request)
-{
- SoupRequestFile *file = SOUP_REQUEST_FILE (request);
- SoupRequestFilePrivate *priv = soup_request_file_get_instance_private (file);
- return priv->size;
-}
-
-static const char *
-soup_request_file_get_content_type (SoupRequest *request)
-{
- SoupRequestFile *file = SOUP_REQUEST_FILE (request);
- SoupRequestFilePrivate *priv = soup_request_file_get_instance_private (file);
-
- if (!priv->mime_type)
- return "application/octet-stream";
-
- return priv->mime_type;
-}
-
-static const char *file_schemes[] = { "file", "resource", NULL };
-
-static void
-soup_request_file_class_init (SoupRequestFileClass *request_file_class)
-{
- GObjectClass *object_class = G_OBJECT_CLASS (request_file_class);
- SoupRequestClass *request_class =
- SOUP_REQUEST_CLASS (request_file_class);
-
- request_class->schemes = file_schemes;
-
- object_class->finalize = soup_request_file_finalize;
-
- request_class->check_uri = soup_request_file_check_uri;
- request_class->send = soup_request_file_send;
- request_class->send_async = soup_request_file_send_async;
- request_class->send_finish = soup_request_file_send_finish;
- request_class->get_content_length = soup_request_file_get_content_length;
- request_class->get_content_type = soup_request_file_get_content_type;
-}
-
-/**
- * soup_request_file_get_file:
- * @file: a #SoupRequestFile
- *
- * Gets a #GFile corresponding to @file's URI
- *
- * Return value: (transfer full): a #GFile corresponding to @file
- *
- * Since: 2.40
- */
-GFile *
-soup_request_file_get_file (SoupRequestFile *file)
-{
- SoupRequestFilePrivate *priv = soup_request_file_get_instance_private (file);
- return g_object_ref (priv->gfile);
-}