Add download and better_copy_file functions into the misc module
authorTomas Mlcoch <tmlcoch@redhat.com>
Wed, 9 May 2012 09:45:42 +0000 (11:45 +0200)
committerTomas Mlcoch <tmlcoch@redhat.com>
Wed, 9 May 2012 09:58:22 +0000 (11:58 +0200)
src/locate_metadata.c
src/misc.c
src/misc.h
tests/testmisc.c

index f4c76d0..38f62d2 100644 (file)
@@ -214,52 +214,6 @@ struct MetadataLocation *get_local_metadata(const char *in_repopath)
 
 
 
-void download(CURL *handle, const char *url, const char *tmp_repo, char **error)
-{
-    CURLcode rcode;
-    gchar *full_path;
-    FILE *file = NULL;
-
-    full_path = g_strconcat(tmp_repo, get_filename(url), NULL);
-    if (!full_path) {
-        *error = g_strdup_printf(MODULE"%s: g_strconcat() error", __func__);
-        return;
-    }
-
-    file = fopen(full_path, "w");
-    if (!file) {
-        *error = g_strdup_printf(MODULE"%s: Cannot open %s", __func__, full_path);
-        goto download_cleanup;
-    }
-
-    // Set URL
-    if (curl_easy_setopt(handle, CURLOPT_URL, url) != CURLE_OK) {
-        *error = g_strdup_printf(MODULE"%s: curl_easy_setopt(CURLOPT_URL) error", __func__);
-        goto download_cleanup;
-    }
-
-    // Set output file descriptor
-    if (curl_easy_setopt(handle, CURLOPT_WRITEDATA, file) != CURLE_OK) {
-        *error = g_strdup_printf(MODULE"%s: curl_easy_setopt(CURLOPT_WRITEDATA) error", __func__);
-        goto download_cleanup;
-    }
-
-    rcode = curl_easy_perform(handle);
-    if (rcode != 0) {
-        *error = g_strdup_printf(MODULE"%s: curl_easy_perform() error: %s", __func__, curl_easy_strerror(rcode));
-    }
-
-
-download_cleanup:
-
-    g_debug(MODULE"%s: Successfully downloaded: %s", __func__, full_path);
-
-    if (file) fclose(file);
-    g_free(full_path);
-}
-
-
-
 struct MetadataLocation *get_remote_metadata(const char *repopath)
 {
     gchar *url = NULL;
index c5767da..820af7f 100644 (file)
@@ -8,6 +8,7 @@
 #include <arpa/inet.h>
 #include <unistd.h>
 #include <ftw.h>
+#include <curl/curl.h>
 #include "logging.h"
 #include "constants.h"
 #include "misc.h"
@@ -445,29 +446,90 @@ int copy_file(const char *src, const char *in_dst)
 }
 
 
-/*
-long int get_file_size(const char *path)
+
+void download(CURL *handle, const char *url, const char *in_dst, char **error)
 {
-    if (!path) {
-        return -1;
+    CURLcode rcode;
+    FILE *file = NULL;
+
+
+    // If destination is dir use filename from src
+
+    gchar *dst = NULL;
+    if (g_str_has_suffix(in_dst, "/")) {
+        dst = g_strconcat(in_dst, get_filename(url), NULL);
+    } else if (g_file_test(in_dst, (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR))) {
+        dst = g_strconcat(in_dst, "/", get_filename(url), NULL);
+    } else {
+        dst = g_strdup(in_dst);
     }
 
-    FILE *f;
-    if ((f = fopen(path, "r")) == NULL) {
-        return -1;
+    file = fopen(dst, "w");
+    if (!file) {
+        *error = g_strdup_printf(MODULE"%s: Cannot open %s", __func__, dst);
+        remove(dst);
+        g_free(dst);
+        return;
     }
 
-    if (fseek(f, 0, SEEK_END) != 0) {
-        return -1;
+
+    // Set URL
+
+    if (curl_easy_setopt(handle, CURLOPT_URL, url) != CURLE_OK) {
+        *error = g_strdup_printf(MODULE"%s: curl_easy_setopt(CURLOPT_URL) error", __func__);
+        fclose(file);
+        remove(dst);
+        g_free(dst);
+        return;
     }
 
-    long int size = ftell(f);
 
-    fclose(f);
+    // Set output file descriptor
+
+    if (curl_easy_setopt(handle, CURLOPT_WRITEDATA, file) != CURLE_OK) {
+        *error = g_strdup_printf(MODULE"%s: curl_easy_setopt(CURLOPT_WRITEDATA) error", __func__);
+        fclose(file);
+        remove(dst);
+        g_free(dst);
+        return;
+    }
 
-    return size;
+    rcode = curl_easy_perform(handle);
+    if (rcode != 0) {
+        *error = g_strdup_printf(MODULE"%s: curl_easy_perform() error: %s", __func__, curl_easy_strerror(rcode));
+        fclose(file);
+        remove(dst);
+        g_free(dst);
+        return;
+    }
+
+
+    g_debug(MODULE"%s: Successfully downloaded: %s", __func__, dst);
+
+    fclose(file);
+    g_free(dst);
+}
+
+
+
+int better_copy_file(const char *src, const char *in_dst)
+{
+    if (!strstr(src, "://")) {
+        // Probably local path
+        return copy_file(src, in_dst);
+    }
+
+    char *error = NULL;
+    CURL *handle = curl_easy_init();
+    download(handle, src, in_dst, &error);
+    curl_easy_cleanup(handle);
+    if (error) {
+        g_debug(MODULE"%s: Error while downloading %s: %s", __func__, src, error);
+        return CR_COPY_ERR;
+    }
+
+    return CR_COPY_OK;
 }
-*/
 
 
 int remove_dir_cb(const char *fpath, const struct stat *sb, int typeflag, struct FTW *ftwbuf)
index 9825d4c..c08a9f2 100644 (file)
@@ -2,6 +2,7 @@
 #define __C_CREATEREPOLIB_MISC_H__
 
 #include <glib.h>
+#include <curl/curl.h>
 #include "constants.h"
 
 #define UNUSED(x) (void)(x) // Used to suppress compiler warning about unused param
@@ -38,7 +39,9 @@ char *get_filename(const char *filepath);
 #define CR_COPY_OK              0
 #define CR_COPY_ERR             1
 
+void download(CURL *handle, const char *url, const char *in_dst, char **error);
 int copy_file(const char *src, const char *dst);
+int better_copy_file(const char *src, const char *dst);
 int remove_dir(const char *path);
 
 // return new allocated string with normalized path or NULL
index 1b0f45f..d345fd1 100644 (file)
 #define TMP_DIR_PATTERN         "/tmp/createrepo_test_XXXXXX"
 #define NON_EXIST_FILE          "/tmp/foobarfile.which.should.not.exists"
 
+#define VALID_URL_01    "http://google.com/index.html"
+#define URL_FILENAME_01 "index.html"
+#define INVALID_URL     "htp://foo.bar"
+
 
 static void test_string_to_version(void)
 {
@@ -460,7 +464,7 @@ static void copyfiletest_setup(Copyfiletest *copyfiletest, gconstpointer test_da
     UNUSED(test_data);
     copyfiletest->tmp_dir = g_strdup(TMP_DIR_PATTERN);
     mkdtemp(copyfiletest->tmp_dir);
-    copyfiletest->dst_file = g_strconcat(copyfiletest->tmp_dir, DST_FILE, NULL);
+    copyfiletest->dst_file = g_strconcat(copyfiletest->tmp_dir, "/", DST_FILE, NULL);
 }
 
 
@@ -557,6 +561,86 @@ static void copyfiletest_test_corner_cases(Copyfiletest *copyfiletest, gconstpoi
 }
 
 
+
+static void test_download_valid_url_1(Copyfiletest *copyfiletest, gconstpointer test_data)
+{
+    UNUSED(test_data);
+
+    char *error = NULL;
+    CURL *handle = curl_easy_init();
+
+    g_assert(!g_file_test(copyfiletest->dst_file, G_FILE_TEST_EXISTS));
+    download(handle, VALID_URL_01, copyfiletest->dst_file, &error);
+    curl_easy_cleanup(handle);
+    g_assert(!error);
+    g_assert(g_file_test(copyfiletest->dst_file, G_FILE_TEST_EXISTS));
+}
+
+
+
+static void test_download_valid_url_2(Copyfiletest *copyfiletest, gconstpointer test_data)
+{
+    UNUSED(test_data);
+
+    char *error = NULL;
+    CURL *handle = curl_easy_init();
+
+    g_assert(!g_file_test(copyfiletest->dst_file, G_FILE_TEST_EXISTS));
+    download(handle, VALID_URL_01, copyfiletest->tmp_dir, &error);
+    curl_easy_cleanup(handle);
+    g_assert(!error);
+    char *dst = g_strconcat(copyfiletest->tmp_dir, "/", URL_FILENAME_01, NULL);
+    g_assert(g_file_test(dst, G_FILE_TEST_EXISTS));
+    g_free(dst);
+}
+
+
+static void test_download_invalid_url(Copyfiletest *copyfiletest, gconstpointer test_data)
+{
+    UNUSED(test_data);
+
+    char *error = NULL;
+    CURL *handle = curl_easy_init();
+
+    g_assert(!g_file_test(copyfiletest->dst_file, G_FILE_TEST_EXISTS));
+    download(handle, INVALID_URL, copyfiletest->dst_file, &error);
+    curl_easy_cleanup(handle);
+    g_assert(error);
+    g_assert(!g_file_test(copyfiletest->dst_file, G_FILE_TEST_EXISTS));
+}
+
+
+
+static void test_better_copy_file_local(Copyfiletest *copyfiletest, gconstpointer test_data)
+{
+    UNUSED(test_data);
+    int ret;
+    char *checksum;
+
+    g_assert(!g_file_test(copyfiletest->dst_file, G_FILE_TEST_EXISTS));
+    ret = better_copy_file(BINARY_FILE, copyfiletest->dst_file);
+    g_assert_cmpint(ret, ==, CR_COPY_OK);
+    g_assert(g_file_test(copyfiletest->dst_file, G_FILE_TEST_EXISTS|G_FILE_TEST_IS_REGULAR));
+    checksum = compute_file_checksum(copyfiletest->dst_file, PKG_CHECKSUM_SHA256);
+    g_assert_cmpstr(checksum, ==, "bf68e32ad78cea8287be0f35b74fa3fecd0eaa91770b48f1a7282b015d6d883e");
+    g_free(checksum);
+}
+
+
+
+static void test_better_copy_file_url(Copyfiletest *copyfiletest, gconstpointer test_data)
+{
+    UNUSED(test_data);
+    int ret;
+
+    g_assert(!g_file_test(copyfiletest->dst_file, G_FILE_TEST_EXISTS));
+    ret = better_copy_file(VALID_URL_01, copyfiletest->dst_file);
+    g_assert_cmpint(ret, ==, CR_COPY_OK);
+    g_assert(g_file_test(copyfiletest->dst_file, G_FILE_TEST_EXISTS|G_FILE_TEST_IS_REGULAR));
+}
+
+
+
 static void test_remove_dir(void)
 {
     char *tmp_dir;
@@ -674,6 +758,11 @@ int main(int argc, char *argv[])
     g_test_add("/misc/copyfiletest_test_binary_file", Copyfiletest, NULL, copyfiletest_setup, copyfiletest_test_binary_file, copyfiletest_teardown);
     g_test_add("/misc/copyfiletest_test_rewrite", Copyfiletest, NULL, copyfiletest_setup, copyfiletest_test_rewrite, copyfiletest_teardown);
     g_test_add("/misc/copyfiletest_test_corner_cases", Copyfiletest, NULL, copyfiletest_setup, copyfiletest_test_corner_cases, copyfiletest_teardown);
+    g_test_add("/misc/test_download_valid_url_1", Copyfiletest, NULL, copyfiletest_setup, test_download_valid_url_1, copyfiletest_teardown);
+    g_test_add("/misc/test_download_valid_url_2", Copyfiletest, NULL, copyfiletest_setup, test_download_valid_url_2, copyfiletest_teardown);
+    g_test_add("/misc/test_download_invalid_url", Copyfiletest, NULL, copyfiletest_setup, test_download_invalid_url, copyfiletest_teardown);
+    g_test_add("/misc/test_better_copy_file_local", Copyfiletest, NULL, copyfiletest_setup, test_better_copy_file_local, copyfiletest_teardown);
+    g_test_add("/misc/test_better_copy_file_url", Copyfiletest, NULL, copyfiletest_setup, test_better_copy_file_url, copyfiletest_teardown);
     g_test_add_func("/misc/test_normalize_dir_path", test_normalize_dir_path);
     g_test_add_func("/misc/test_remove_dir", test_remove_dir);