[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Bug-wget] [PATCH 19/27] New: Parse Metalink/HTTP header for application
From: |
Matthew White |
Subject: |
[Bug-wget] [PATCH 19/27] New: Parse Metalink/HTTP header for application/metalink4+xml |
Date: |
Thu, 29 Sep 2016 06:02:59 +0200 |
* src/http.c (metalink_from_http): Parse Metalink/HTTP header for
metaurls application/metalink4+xml media types
* src/metalink.h: Add function declaration metalink_meta_cmp()
* src/metalink.c: Add function metalink_meta_cmp() compare metalink
metaurls priorities
Add Metalink/HTTP application/metalink4+xml media types as metaurls to
the metalink variable that will be used to download the files.
---
src/http.c | 71 ++++++++++++++++++++++++++++++++++++++++++++++++++++------
src/metalink.c | 9 ++++++++
src/metalink.h | 1 +
3 files changed, 74 insertions(+), 7 deletions(-)
diff --git a/src/http.c b/src/http.c
index 7e2c4ec..e6af7c1 100644
--- a/src/http.c
+++ b/src/http.c
@@ -2555,7 +2555,7 @@ metalink_from_http (const struct response *resp, const
struct http_stat *hs,
metalink_t *metalink = NULL;
metalink_file_t *mfile = xnew0 (metalink_file_t);
const char *val_beg, *val_end;
- int res_count = 0, hash_count = 0, sig_count = 0, i;
+ int res_count = 0, meta_count = 0, hash_count = 0, sig_count = 0, i;
DEBUGP (("Checking for Metalink in HTTP response\n"));
@@ -2568,6 +2568,7 @@ metalink_from_http (const struct response *resp, const
struct http_stat *hs,
/* Begin with 1-element array (for 0-termination). */
mfile->checksums = xnew0 (metalink_checksum_t *);
mfile->resources = xnew0 (metalink_resource_t *);
+ mfile->metaurls = xnew0 (metalink_metaurl_t *);
/* Find all Link headers. */
for (i = 0;
@@ -2628,14 +2629,14 @@ metalink_from_http (const struct response *resp, const
struct http_stat *hs,
DEBUGP (("URL=%s\n", urlstr));
DEBUGP (("rel=%s\n", rel));
+ if (!strcmp (rel, "describedby"))
+ find_key_value (attrs_beg, val_end, "type", &reltype);
+
/* Handle signatures.
Libmetalink only supports one signature per file. Therefore we stop
as soon as we successfully get first supported signature. */
if (sig_count == 0 &&
- !strcmp (rel, "describedby") &&
- find_key_value (attrs_beg, val_end, "type", &reltype) &&
- !strcmp (reltype, "application/pgp-signature")
- )
+ reltype && !strcmp (reltype, "application/pgp-signature"))
{
/* Download the signature to a temporary file. */
FILE *_output_stream = output_stream;
@@ -2801,6 +2802,60 @@ metalink_from_http (const struct response *resp, const
struct http_stat *hs,
res_count++;
}
} /* Handle resource link (rel=duplicate). */
+
+ /* Handle Metalink/XML resources. */
+ else if (reltype && !strcmp (reltype, "application/metalink4+xml"))
+ {
+ metalink_metaurl_t murl = {0};
+ char *pristr;
+
+ /*
+ Valid ranges for the "pri" attribute are from
+ 1 to 999999. Mirror servers with a lower value of the "pri"
+ attribute have a higher priority, while mirrors with an undefined
+ "pri" attribute are considered to have a value of 999999, which is
+ the lowest priority.
+
+ rfc6249 section 3.1
+ */
+ murl.priority = DEFAULT_PRI;
+ if (find_key_value (url_end, val_end, "pri", &pristr))
+ {
+ long pri;
+ char *end_pristr;
+ /* Do not care for errno since 0 is error in this case. */
+ pri = strtol (pristr, &end_pristr, 10);
+ if (end_pristr != pristr + strlen (pristr) ||
+ !VALID_PRI_RANGE (pri))
+ {
+ /* This is against the specification, so let's inform the
user. */
+ logprintf (LOG_NOTQUIET,
+ _("Invalid pri value. Assuming %d.\n"),
+ DEFAULT_PRI);
+ }
+ else
+ murl.priority = pri;
+ xfree (pristr);
+ }
+
+ murl.mediatype = xstrdup (reltype);
+
+ DEBUGP (("MEDIATYPE=%s\n", murl.mediatype));
+
+ /* At this point we have validated the new resource. */
+
+ find_key_value (url_end, val_end, "name", &murl.name);
+
+ murl.url = urlstr;
+ urlstr = NULL;
+
+ /* 1 slot from new resource, 1 slot for null-termination. */
+ mfile->metaurls = xrealloc (mfile->metaurls,
+ sizeof (metalink_metaurl_t *) *
(meta_count + 2));
+ mfile->metaurls[meta_count] = xnew0 (metalink_metaurl_t);
+ *mfile->metaurls[meta_count] = murl;
+ meta_count++;
+ } /* Handle resource link (rel=describedby). */
else
DEBUGP (("This link header was not used for Metalink\n"));
@@ -2811,8 +2866,9 @@ metalink_from_http (const struct response *resp, const
struct http_stat *hs,
/* Null-terminate resources array. */
mfile->resources[res_count] = 0;
+ mfile->metaurls[meta_count] = 0;
- if (res_count == 0)
+ if (res_count == 0 && meta_count == 0)
{
DEBUGP (("No valid metalink references found.\n"));
goto fail;
@@ -2867,7 +2923,7 @@ metalink_from_http (const struct response *resp, const
struct http_stat *hs,
rfc6249 section 6
*/
- if (hash_count == 0)
+ if (res_count && hash_count == 0)
{
logputs (LOG_VERBOSE,
_("Could not find acceptable digest for Metalink resources.\n"
@@ -2878,6 +2934,7 @@ metalink_from_http (const struct response *resp, const
struct http_stat *hs,
/* Metalink data is OK. Now we just need to sort the resources based
on their priorities, preference, and perhaps location. */
stable_sort (mfile->resources, res_count, sizeof (metalink_resource_t *),
metalink_res_cmp);
+ stable_sort (mfile->metaurls, meta_count, sizeof (metalink_metaurl_t *),
metalink_meta_cmp);
/* Restore sensible preference values (in case someone cares to look). */
for (i = 0; i < res_count; ++i)
diff --git a/src/metalink.c b/src/metalink.c
index b7f3a72..29cfee7 100644
--- a/src/metalink.c
+++ b/src/metalink.c
@@ -913,6 +913,15 @@ int metalink_res_cmp (const void* v1, const void* v2)
return 0;
}
+int metalink_meta_cmp (const void* v1, const void* v2)
+{
+ const metalink_metaurl_t *meta1 = *(metalink_metaurl_t **) v1,
+ *meta2 = *(metalink_metaurl_t **) v2;
+ if (meta1->priority != meta2->priority)
+ return meta1->priority - meta2->priority;
+ return 0;
+}
+
/*
Find value of given key. This is intended for Link header, but will
work with any header that uses ';' as field separator and '=' as key-value
diff --git a/src/metalink.h b/src/metalink.h
index 6bd61f5..ed8c62f 100644
--- a/src/metalink.h
+++ b/src/metalink.h
@@ -46,6 +46,7 @@ as that of the covered work. */
uerr_t retrieve_from_metalink (const metalink_t *metalink);
int metalink_res_cmp (const void *res1, const void *res2);
+int metalink_meta_cmp (const void* meta1, const void* meta2);
int metalink_check_safe_path (const char *path);
--
2.7.3
- [Bug-wget] [PATCH 08/27] Add file size computation in Metalink module, (continued)
- [Bug-wget] [PATCH 08/27] Add file size computation in Metalink module, Matthew White, 2016/09/29
- [Bug-wget] [PATCH 10/27] Implement Metalink/XML --directory-prefix option in Metalink module, Matthew White, 2016/09/29
- [Bug-wget] [PATCH 11/27] Enforce Metalink file name verification, strip directory if necessary, Matthew White, 2016/09/29
- [Bug-wget] [PATCH 12/27] New document: Metalink/XML and Metalink/HTTP standard reference, Matthew White, 2016/09/29
- [Bug-wget] [PATCH 14/27] New: Metalink file size mismatch returns error code METALINK_SIZE_ERROR, Matthew White, 2016/09/29
- [Bug-wget] [PATCH 15/27] New test: Detect when there are no good Metalink url resources, Matthew White, 2016/09/29
- [Bug-wget] [PATCH 16/27] Bugfix: Process Metalink/XML url strings containing white spaces and CRLF, Matthew White, 2016/09/29
- [Bug-wget] [PATCH 17/27] Bugfix: Remove surrounding quotes from Metalink/HTTP key's value, Matthew White, 2016/09/29
- [Bug-wget] [PATCH 18/27] New test: Metalink shall not concatenate '/' to an empty directory prefix, Matthew White, 2016/09/29
- [Bug-wget] [PATCH 19/27] New: Parse Metalink/HTTP header for application/metalink4+xml,
Matthew White <=
- [Bug-wget] [PATCH 20/27] Bugfix: Prevent sorting when there are less than two elements, Matthew White, 2016/09/29
- [Bug-wget] [PATCH 13/27] New: Metalink/XML and Metalink/HTTP file naming safety rules, Matthew White, 2016/09/29
- [Bug-wget] [PATCH 23/27] Bugfix: Detect when a metalink:file doesn't have any hash, Matthew White, 2016/09/29
- [Bug-wget] [PATCH 22/27] Bugfix: Detect malformed base64 Metalink/HTTP Digest header, Matthew White, 2016/09/29
- [Bug-wget] [PATCH 21/27] New option --metalink-index to process Metalink application/metalink4+xml, Matthew White, 2016/09/29
- [Bug-wget] [PATCH 25/27] Bugfix: Set NULL variable due to --content-disposition to Metalink origin, Matthew White, 2016/09/29
- [Bug-wget] [PATCH 24/27] New: --trust-server-names saves Metalink/HTTP xml files using the "name" field, Matthew White, 2016/09/29