]> Pileus Git - grits/blobdiff - src/data/grits-http.c
Add grits_http_abort function
[grits] / src / data / grits-http.c
index 7f7d03be9393978f21aff9039749d745e718cff9..45b30df0f767b94b7cf98fa50735f860dd0a239a 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2009-2010 Andy Spencer <andy753421@gmail.com>
+ * Copyright (C) 2009-2011 Andy Spencer <andy753421@gmail.com>
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  */
 
 /**
- * SECTION:gis-http
+ * SECTION:grits-http
  * @short_description: Hyper Text Transfer Protocol
  *
- * #GisHttp is a small wrapper around libsoup to provide data access using the
- * Hyper Text Transfer Protocol. Each #GisHttp should be associated with a
- * particular server or dataset, all the files downloaded for this dataset will
- * be cached together in $HOME.cache/libgis/
+ * #GritsHttp is a small wrapper around libsoup to provide data access using
+ * the Hyper Text Transfer Protocol. Each #GritsHttp should be associated with
+ * a particular server or dataset, all the files downloaded for this dataset
+ * will be cached together in $HOME/.cache/grits/
  */
 
 #include <config.h>
 #include <glib/gstdio.h>
 #include <libsoup/soup.h>
 
-#include "gis-http.h"
+#include "grits-http.h"
 
-gchar *_get_cache_path(GisHttp *http, const gchar *local)
+gchar *_get_cache_path(GritsHttp *http, const gchar *local)
 {
        return g_build_filename(g_get_user_cache_dir(), PACKAGE,
                        http->prefix, local, NULL);
 }
 
 /**
- * gis_http_new:
+ * grits_http_new:
  * @prefix: The prefix in the cache to store the downloaded files.
  *          For example: * "/nexrad/level2/".
  *
- * Create a new #GisHttp for the given prefix
+ * Create a new #GritsHttp for the given prefix
  *
- * Returns: the new #GisHttp
+ * Returns: the new #GritsHttp
  */
-GisHttp *gis_http_new(const gchar *prefix)
+GritsHttp *grits_http_new(const gchar *prefix)
 {
-       g_debug("GisHttp: new - %s", prefix);
-       GisHttp *http = g_new0(GisHttp, 1);
+       g_debug("GritsHttp: new - %s", prefix);
+       GritsHttp *http = g_new0(GritsHttp, 1);
        http->soup = soup_session_sync_new();
        http->prefix = g_strdup(prefix);
        g_object_set(http->soup, "user-agent", PACKAGE_STRING, NULL);
+       g_object_set(http->soup, "timeout",    10,             NULL);
        return http;
 }
 
 /**
- * gis_http_free:
- * @http: the #GisHttp to free
+ * grits_http_abort:
+ * @http: the #GritsHttp to abort
  *
- * Frees resources used by @http and cancels any pending requests.
+ * Cancels any pending requests and prevents new requests.
  */
-void gis_http_free(GisHttp *http)
+void grits_http_abort(GritsHttp *http)
 {
-       g_debug("GisHttp: free - %s", http->prefix);
+       g_debug("GritsHttp: abort - %s", http->prefix);
+       http->aborted = TRUE;
        soup_session_abort(http->soup);
+}
+
+/**
+ * grits_http_free:
+ * @http: the #GritsHttp to free
+ *
+ * Frees resources used by @http and cancels any pending requests.
+ */
+void grits_http_free(GritsHttp *http)
+{
+       g_debug("GritsHttp: free - %s", http->prefix);
        g_object_unref(http->soup);
        g_free(http->prefix);
        g_free(http);
@@ -76,12 +89,12 @@ void gis_http_free(GisHttp *http)
 struct _CacheInfo {
        FILE  *fp;
        gchar *path;
-       GisChunkCallback callback;
+       GritsChunkCallback callback;
        gpointer user_data;
 };
 struct _CacheInfoMain {
        gchar *path;
-       GisChunkCallback callback;
+       GritsChunkCallback callback;
        gpointer user_data;
        goffset cur, total;
 };
@@ -106,13 +119,13 @@ static void _chunk_cb(SoupMessage *message, SoupBuffer *chunk, gpointer _info)
        struct _CacheInfo *info = _info;
 
        if (!SOUP_STATUS_IS_SUCCESSFUL(message->status_code)) {
-               g_warning("GisHttp: _chunk_cb - soup failed with %d",
+               g_warning("GritsHttp: _chunk_cb - soup failed with %d",
                                message->status_code);
                return;
        }
 
        if (!fwrite(chunk->data, chunk->length, 1, info->fp))
-               g_error("GisHttp: _chunk_cb - Unable to write data");
+               g_error("GritsHttp: _chunk_cb - Unable to write data");
 
        if (info->callback) {
                struct _CacheInfoMain *infomain = g_new0(struct _CacheInfoMain, 1);
@@ -129,8 +142,8 @@ static void _chunk_cb(SoupMessage *message, SoupBuffer *chunk, gpointer _info)
 }
 
 /**
- * gis_http_fetch:
- * @http:      the #GisHttp connection to use
+ * grits_http_fetch:
+ * @http:      the #GritsHttp connection to use
  * @uri:       the URI to fetch
  * @local:     the local name to give to the file
  * @mode:      the update type to use when fetching data
@@ -142,27 +155,35 @@ static void _chunk_cb(SoupMessage *message, SoupBuffer *chunk, gpointer _info)
  *
  * Returns: The local path to the complete file
  */
-/* TODO: use .part extentions and continue even when using GIS_ONCE */
-gchar *gis_http_fetch(GisHttp *http, const gchar *uri, const char *local,
-               GisCacheType mode, GisChunkCallback callback, gpointer user_data)
+/* TODO: use .part extentions and continue even when using GRITS_ONCE */
+gchar *grits_http_fetch(GritsHttp *http, const gchar *uri, const char *local,
+               GritsCacheType mode, GritsChunkCallback callback, gpointer user_data)
 {
-       g_debug("GisHttp: fetch - %s mode=%d", local, mode);
+       g_debug("GritsHttp: fetch - %s mode=%d", local, mode);
+       if (http->aborted) {
+               g_debug("GritsPluginSat: _load_tile_thread - aborted");
+               return NULL;
+       }
        gchar *path = _get_cache_path(http, local);
 
        /* Unlink the file if we're refreshing it */
-       if (mode == GIS_REFRESH)
+       if (mode == GRITS_REFRESH)
                g_remove(path);
 
        /* Do the cache if necessasairy */
-       if (!(mode == GIS_ONCE && g_file_test(path, G_FILE_TEST_EXISTS)) &&
-                       mode != GIS_LOCAL) {
-               g_debug("GisHttp: fetch - Caching file %s", local);
+       if (!(mode == GRITS_ONCE && g_file_test(path, G_FILE_TEST_EXISTS)) &&
+                       mode != GRITS_LOCAL) {
+               g_debug("GritsHttp: fetch - Caching file %s", local);
 
                /* Open the file for writting */
                gchar *part = path;
                if (!g_file_test(path, G_FILE_TEST_EXISTS))
                        part = g_strdup_printf("%s.part", path);
                FILE *fp = fopen_p(part, "ab");
+               if (!fp) {
+                       g_warning("GritsHttp: fetch - error opening %s", path);
+                       return NULL;
+               }
                fseek(fp, 0, SEEK_END); // "a" is broken on Windows, twice
 
                /* Make temp data */
@@ -178,36 +199,44 @@ gchar *gis_http_fetch(GisHttp *http, const gchar *uri, const char *local,
                if (message == NULL)
                        g_error("message is null, cannot parse uri");
                g_signal_connect(message, "got-chunk", G_CALLBACK(_chunk_cb), &info);
-               soup_message_headers_set_range(message->request_headers, ftell(fp), -1);
+               //if (ftell(fp) > 0)
+                       soup_message_headers_set_range(message->request_headers, ftell(fp), -1);
+               if (mode == GRITS_REFRESH)
+                       soup_message_headers_replace(message->request_headers,
+                                       "Cache-Control", "max-age=0");
                soup_session_send_message(http->soup, message);
 
                /* Close file */
                fclose(fp);
-               if (path != part && SOUP_STATUS_IS_SUCCESSFUL(message->status_code)) {
-                       g_rename(part, path);
+               if (path != part) {
+                       if (SOUP_STATUS_IS_SUCCESSFUL(message->status_code))
+                               g_rename(part, path);
                        g_free(part);
                }
 
                /* Finished */
-               if (message->status_code == 416) {
+               guint status = message->status_code;
+               g_object_unref(message);
+               if (status == SOUP_STATUS_CANCELLED) {
+                       return NULL;
+               } else if (status == SOUP_STATUS_REQUESTED_RANGE_NOT_SATISFIABLE) {
                        /* Range unsatisfiable, file already complete */
-               } else if (!SOUP_STATUS_IS_SUCCESSFUL(message->status_code)) {
-                       g_warning("GisHttp: done_cb - error copying file, status=%d\n"
+               } else if (!SOUP_STATUS_IS_SUCCESSFUL(status)) {
+                       g_warning("GritsHttp: done_cb - error copying file, status=%d\n"
                                        "\tsrc=%s\n"
                                        "\tdst=%s",
-                                       message->status_code, uri, path);
+                                       status, uri, path);
                        return NULL;
                }
        }
 
-
        /* TODO: free everything.. */
        return path;
 }
 
 /**
- * gis_http_available:
- * @http:    the #GisHttp connection to use
+ * grits_http_available:
+ * @http:    the #GritsHttp connection to use
  * @filter:  filter used to extract files from the index, or NULL
  *           For example: "href=\"([^"]*)\""
  * @cache:   path to the local cache, or NULL to not search the cache
@@ -222,11 +251,11 @@ gchar *gis_http_fetch(GisHttp *http, const gchar *uri, const char *local,
  *
  * Returns the list of matching filenames
  */
-GList *gis_http_available(GisHttp *http,
+GList *grits_http_available(GritsHttp *http,
                gchar *filter, gchar *cache,
                gchar *extract, gchar *index)
 {
-       g_debug("GisHttp: available - %s~=%s %s~=%s",
+       g_debug("GritsHttp: available - %s~=%s %s~=%s",
                        filter, cache, extract, index);
        GRegex *filter_re = g_regex_new(filter, 0, 0, NULL);
        GList  *files = NULL;
@@ -236,19 +265,20 @@ GList *gis_http_available(GisHttp *http,
                const gchar *file;
                gchar *path = _get_cache_path(http, cache);
                GDir  *dir  = g_dir_open(path, 0, NULL);
-               while ((file = g_dir_read_name(dir)))
+               while (dir && (file = g_dir_read_name(dir)))
                        if (g_regex_match(filter_re, file, 0, NULL))
                                files = g_list_prepend(files, g_strdup(file));
                g_free(path);
-               g_dir_close(dir);
+               if (dir)
+                       g_dir_close(dir);
        }
 
        /* Add online files if online */
        if (index) {
                gchar tmp[32];
                g_snprintf(tmp, sizeof(tmp), ".index.%x", g_random_int());
-               gchar *path = gis_http_fetch(http, index, tmp,
-                               GIS_REFRESH, NULL, NULL);
+               gchar *path = grits_http_fetch(http, index, tmp,
+                               GRITS_REFRESH, NULL, NULL);
                if (!path)
                        return files;
                gchar *html;