]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
import: allow file:// in addition to HTTP(S)
authorLennart Poettering <lennart@poettering.net>
Thu, 19 Aug 2021 16:15:37 +0000 (18:15 +0200)
committerLennart Poettering <lennart@poettering.net>
Fri, 20 Aug 2021 19:56:39 +0000 (21:56 +0200)
Previously we only allows http/https urls, let's open this up a bit.
Why? Because it makes testing *so* *much* *easier* as we don't need to
run a HTTP server all the time.

CURL mostly abstracts the differences of http/https away from us, hence
we can get away with very little extra work.

src/import/importd.c
src/import/pull-job.c
src/import/pull-raw.c
src/import/pull-tar.c
src/import/pull.c
src/machine/machinectl.c
src/shared/web-util.c
src/shared/web-util.h

index 0a870568194d8453dde4722fc4afc65988c06978..86181628d9d6b3200e23a41b681c026c53960733 100644 (file)
@@ -928,7 +928,7 @@ static int method_pull_tar_or_raw(sd_bus_message *msg, void *userdata, sd_bus_er
         if (r < 0)
                 return r;
 
-        if (!http_url_is_valid(remote))
+        if (!http_url_is_valid(remote) && !file_url_is_valid(remote))
                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS,
                                          "URL %s is invalid", remote);
 
index 8764207960b676e8cec4b2526950983a8078d368..826da953785d2b777c08ef15bd4a1a40d34aefdd 100644 (file)
@@ -117,7 +117,7 @@ static int pull_job_restart(PullJob *j, const char *new_url) {
 void pull_job_curl_on_finished(CurlGlue *g, CURL *curl, CURLcode result) {
         PullJob *j = NULL;
         CURLcode code;
-        long status;
+        long protocol;
         int r;
 
         if (curl_easy_getinfo(curl, CURLINFO_PRIVATE, (char **)&j) != CURLE_OK)
@@ -131,50 +131,62 @@ void pull_job_curl_on_finished(CurlGlue *g, CURL *curl, CURLcode result) {
                 goto finish;
         }
 
-        code = curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &status);
+        code = curl_easy_getinfo(curl, CURLINFO_PROTOCOL, &protocol);
         if (code != CURLE_OK) {
                 r = log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to retrieve response code: %s", curl_easy_strerror(code));
                 goto finish;
-        } else if (status == 304) {
-                log_info("Image already downloaded. Skipping download.");
-                j->etag_exists = true;
-                r = 0;
-                goto finish;
-        } else if (status >= 300) {
+        }
 
-                if (status == 404 && j->on_not_found) {
-                        _cleanup_free_ char *new_url = NULL;
+        if (IN_SET(protocol, CURLPROTO_HTTP, CURLPROTO_HTTPS)) {
+                long status;
 
-                        /* This resource wasn't found, but the implementor wants to maybe let us know a new URL, query for it. */
-                        r = j->on_not_found(j, &new_url);
-                        if (r < 0)
-                                goto finish;
+                code = curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &status);
+                if (code != CURLE_OK) {
+                        r = log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to retrieve response code: %s", curl_easy_strerror(code));
+                        goto finish;
+                }
+
+                if (status == 304) {
+                        log_info("Image already downloaded. Skipping download.");
+                        j->etag_exists = true;
+                        r = 0;
+                        goto finish;
+                } else if (status >= 300) {
 
-                        if (r > 0) { /* A new url to use */
-                                assert(new_url);
+                        if (status == 404 && j->on_not_found) {
+                                _cleanup_free_ char *new_url = NULL;
 
-                                r = pull_job_restart(j, new_url);
+                                /* This resource wasn't found, but the implementor wants to maybe let us know a new URL, query for it. */
+                                r = j->on_not_found(j, &new_url);
                                 if (r < 0)
                                         goto finish;
 
-                                code = curl_easy_getinfo(j->curl, CURLINFO_RESPONSE_CODE, &status);
-                                if (code != CURLE_OK) {
-                                        r = log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to retrieve response code: %s", curl_easy_strerror(code));
-                                        goto finish;
-                                }
+                                if (r > 0) { /* A new url to use */
+                                        assert(new_url);
+
+                                        r = pull_job_restart(j, new_url);
+                                        if (r < 0)
+                                                goto finish;
+
+                                        code = curl_easy_getinfo(j->curl, CURLINFO_RESPONSE_CODE, &status);
+                                        if (code != CURLE_OK) {
+                                                r = log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to retrieve response code: %s", curl_easy_strerror(code));
+                                                goto finish;
+                                        }
 
-                                if (status == 0)
-                                        return;
+                                        if (status == 0)
+                                                return;
+                                }
                         }
-                }
 
-                r = log_error_errno(
-                                status == 404 ? SYNTHETIC_ERRNO(ENOMEDIUM) : SYNTHETIC_ERRNO(EIO), /* Make the most common error recognizable */
-                                "HTTP request to %s failed with code %li.", j->url, status);
-                goto finish;
-        } else if (status < 200) {
-                r = log_error_errno(SYNTHETIC_ERRNO(EIO), "HTTP request to %s finished with unexpected code %li.", j->url, status);
-                goto finish;
+                        r = log_error_errno(
+                                        status == 404 ? SYNTHETIC_ERRNO(ENOMEDIUM) : SYNTHETIC_ERRNO(EIO), /* Make the most common error recognizable */
+                                        "HTTP request to %s failed with code %li.", j->url, status);
+                        goto finish;
+                } else if (status < 200) {
+                        r = log_error_errno(SYNTHETIC_ERRNO(EIO), "HTTP request to %s finished with unexpected code %li.", j->url, status);
+                        goto finish;
+                }
         }
 
         if (j->state != PULL_JOB_RUNNING) {
index c071e134f29c34912858c898b62800d810f0d673..6a0c2c8b1778faae636333ef042e6e2e35dc0d2a 100644 (file)
@@ -835,7 +835,7 @@ int raw_pull_start(
         assert(!(flags & (PULL_SETTINGS|PULL_ROOTHASH|PULL_ROOTHASH_SIGNATURE|PULL_VERITY)) || !(flags & PULL_DIRECT));
         assert(!(flags & (PULL_SETTINGS|PULL_ROOTHASH|PULL_ROOTHASH_SIGNATURE|PULL_VERITY)) || !checksum);
 
-        if (!http_url_is_valid(url))
+        if (!http_url_is_valid(url) && !file_url_is_valid(url))
                 return -EINVAL;
 
         if (local && !pull_validate_local(local, flags))
index 6aca3c9979b015a860fcf204966d59ffd06364c1..06d336bca91ca717f82fbc94204b8e1c84d36f3e 100644 (file)
@@ -597,7 +597,7 @@ int tar_pull_start(
         assert(!(flags & PULL_SETTINGS) || !(flags & PULL_DIRECT));
         assert(!(flags & PULL_SETTINGS) || !checksum);
 
-        if (!http_url_is_valid(url))
+        if (!http_url_is_valid(url) && !file_url_is_valid(url))
                 return -EINVAL;
 
         if (local && !pull_validate_local(local, flags))
index a903c35aa77b8c50f98017925cafa303c3b5eead..2cf0cca14ff8857ba21d4c7d1a9222ff84587ff7 100644 (file)
@@ -110,7 +110,7 @@ static int pull_tar(int argc, char *argv[], void *userdata) {
         int r;
 
         url = argv[1];
-        if (!http_url_is_valid(url))
+        if (!http_url_is_valid(url) && !file_url_is_valid(url))
                 return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "URL '%s' is not valid.", url);
 
         if (argc >= 3)
@@ -183,7 +183,7 @@ static int pull_raw(int argc, char *argv[], void *userdata) {
         int r;
 
         url = argv[1];
-        if (!http_url_is_valid(url))
+        if (!http_url_is_valid(url) && !file_url_is_valid(url))
                 return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "URL '%s' is not valid.", url);
 
         if (argc >= 3)
index 3f4ad87897243c7c675394669a023a325b68852f..c3a2384f1500d9eb4d09525e0b42ae0bf54c1e63 100644 (file)
@@ -2125,7 +2125,7 @@ static int pull_tar(int argc, char *argv[], void *userdata) {
         assert(bus);
 
         remote = argv[1];
-        if (!http_url_is_valid(remote))
+        if (!http_url_is_valid(remote) && !file_url_is_valid(remote))
                 return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
                                        "URL '%s' is not valid.", remote);
 
@@ -2181,7 +2181,7 @@ static int pull_raw(int argc, char *argv[], void *userdata) {
         assert(bus);
 
         remote = argv[1];
-        if (!http_url_is_valid(remote))
+        if (!http_url_is_valid(remote) && !file_url_is_valid(remote))
                 return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
                                        "URL '%s' is not valid.", remote);
 
index 82cd5fbd6bb245686c33ce0827d2f77843da5b32..39a300f5c96b1cf73ad76daf6b2638311c0fef7a 100644 (file)
@@ -36,16 +36,29 @@ bool http_url_is_valid(const char *url) {
         return ascii_is_valid(p);
 }
 
+bool file_url_is_valid(const char *url) {
+        const char *p;
+
+        if (isempty(url))
+                return false;
+
+        p = startswith(url, "file:/");
+        if (isempty(p))
+                return false;
+
+        return ascii_is_valid(p);
+}
+
 bool documentation_url_is_valid(const char *url) {
         const char *p;
 
         if (isempty(url))
                 return false;
 
-        if (http_url_is_valid(url))
+        if (http_url_is_valid(url) || file_url_is_valid(url))
                 return true;
 
-        p = STARTSWITH_SET(url, "file:/", "info:", "man:");
+        p = STARTSWITH_SET(url, "info:", "man:");
         if (isempty(p))
                 return false;
 
index ec54669f50131e4be05e6d79dd62b45ac638da71..88b4897be0599afb7100a1966e59d1aae6cb7c9f 100644 (file)
@@ -6,6 +6,7 @@
 #include "macro.h"
 
 bool http_url_is_valid(const char *url) _pure_;
+bool file_url_is_valid(const char *url) _pure_;
 
 bool documentation_url_is_valid(const char *url) _pure_;