From dcf395ddb16ed6cbef4214d273f21b32b183f0eb Mon Sep 17 00:00:00 2001 From: Ubuntu Date: Thu, 25 Jun 2015 22:15:05 +0000 Subject: [PATCH] Append the query string portion of a URI to the drive path when in HTTP or HTTPS protocols --- .gitignore | 1 + fish/options.c | 5 +++++ fish/options.h | 1 + fish/uri.c | 28 ++++++++++++++++++++-------- fish/uri.h | 1 + generator/actions.ml | 2 +- src/drives.c | 22 ++++++++++++++++++++-- src/launch-direct.c | 2 +- 8 files changed, 50 insertions(+), 12 deletions(-) diff --git a/.gitignore b/.gitignore index 6f14915..efa7179 100644 --- a/.gitignore +++ b/.gitignore @@ -27,6 +27,7 @@ cscope.out .libs Makefile Makefile.in +tags /.sc-* /ABOUT-NLS diff --git a/fish/options.c b/fish/options.c index b1be711..0e4b468 100644 --- a/fish/options.c +++ b/fish/options.c @@ -64,6 +64,7 @@ option_a (const char *arg, const char *format, struct drv **drvsp) drv->type = drv_uri; drv->nr_drives = -1; drv->uri.path = uri.path; + drv->uri.query = uri.query; drv->uri.protocol = uri.protocol; drv->uri.server = uri.server; drv->uri.username = uri.username; @@ -172,6 +173,10 @@ add_drives_handle (guestfs_h *g, struct drv *drv, char next_drive) ad_optargs.bitmask |= GUESTFS_ADD_DRIVE_OPTS_SECRET_BITMASK; ad_optargs.secret = drv->uri.password; } + if (drv->uri.query) { + ad_optargs.bitmask |= GUESTFS_ADD_DRIVE_OPTS_QUERY_BITMASK; + ad_optargs.query = drv->uri.query; + } r = guestfs_add_drive_opts_argv (g, drv->uri.path, &ad_optargs); if (r == -1) diff --git a/fish/options.h b/fish/options.h index 0348676..b088303 100644 --- a/fish/options.h +++ b/fish/options.h @@ -71,6 +71,7 @@ struct drv { } a; struct { char *path; /* disk path */ + char *query; /* query string */ char *protocol; /* protocol (eg. "nbd") */ char **server; /* server(s) - can be NULL */ char *username; /* username - can be NULL */ diff --git a/fish/uri.c b/fish/uri.c index 593e62a..c74baa2 100644 --- a/fish/uri.c +++ b/fish/uri.c @@ -34,7 +34,7 @@ #include "uri.h" static int is_uri (const char *arg); -static int parse (const char *arg, char **path_ret, char **protocol_ret, char ***server_ret, char **username_ret, char **password_ret); +static int parse (const char *arg, char **path_ret, char **query_ret, char **protocol_ret, char ***server_ret, char **username_ret, char **password_ret); static char *query_get (xmlURIPtr uri, const char *search_name); static int make_server (xmlURIPtr uri, const char *socket, char ***ret); @@ -42,6 +42,7 @@ int parse_uri (const char *arg, struct uri *uri_ret) { char *path = NULL; + char *query = NULL; char *protocol = NULL; char **server = NULL; char *username = NULL; @@ -49,7 +50,7 @@ parse_uri (const char *arg, struct uri *uri_ret) /* Does it look like a URI? */ if (is_uri (arg)) { - if (parse (arg, &path, &protocol, &server, &username, &password) == -1) + if (parse (arg, &path, &query, &protocol, &server, &username, &password) == -1) return -1; } else { @@ -68,6 +69,7 @@ parse_uri (const char *arg, struct uri *uri_ret) } uri_ret->path = path; + uri_ret->query = query; uri_ret->protocol = protocol; uri_ret->server = server; uri_ret->username = username; @@ -100,12 +102,11 @@ is_uri (const char *arg) } static int -parse (const char *arg, char **path_ret, char **protocol_ret, +parse (const char *arg, char **path_ret, char **query_ret, char **protocol_ret, char ***server_ret, char **username_ret, char **password_ret) { CLEANUP_XMLFREEURI xmlURIPtr uri = NULL; CLEANUP_FREE char *socket = NULL; - char *path; uri = xmlParseURI (arg); if (!uri) { @@ -183,15 +184,15 @@ parse (const char *arg, char **path_ret, char **protocol_ret, * exportname expected will be "pool/disk". Here, uri->path will be * "/pool/disk" so we have to knock off the leading '/' character. */ - path = uri->path; - if (path && path[0] == '/' && + char *tmpPath = uri->path; + if (tmpPath && tmpPath[0] == '/' && (STREQ (uri->scheme, "gluster") || STREQ (uri->scheme, "iscsi") || STREQ (uri->scheme, "rbd") || STREQ (uri->scheme, "sheepdog"))) - path++; + tmpPath++; - *path_ret = strdup (path ? path : ""); + *path_ret = strdup (tmpPath ? tmpPath : ""); if (*path_ret == NULL) { perror ("strdup: path"); free (*protocol_ret); @@ -201,6 +202,17 @@ parse (const char *arg, char **path_ret, char **protocol_ret, return -1; } + *query_ret = strdup(uri->query_raw ? uri->query_raw : ""); + if (*query_ret == NULL) { + perror ("strdup: query"); + free (*protocol_ret); + guestfs_int_free_string_list (*server_ret); + free (*username_ret); + free (*password_ret); + free (*path_ret); + return -1; + } + return 0; } diff --git a/fish/uri.h b/fish/uri.h index 9202a70..b851e98 100644 --- a/fish/uri.h +++ b/fish/uri.h @@ -23,6 +23,7 @@ struct uri { char *path; /* disk path */ + char *query; /* query string */ char *protocol; /* protocol (eg. "file", "nbd") */ char **server; /* server(s) - can be NULL */ char *username; /* username - can be NULL */ diff --git a/generator/actions.ml b/generator/actions.ml index d5e5ccf..75b52ea 100644 --- a/generator/actions.ml +++ b/generator/actions.ml @@ -1336,7 +1336,7 @@ not all belong to a single logical operating system { defaults with name = "add_drive"; added = (0, 0, 3); - style = RErr, [String "filename"], [OBool "readonly"; OString "format"; OString "iface"; OString "name"; OString "label"; OString "protocol"; OStringList "server"; OString "username"; OString "secret"; OString "cachemode"; OString "discard"; OBool "copyonread"]; + style = RErr, [String "filename"], [OBool "readonly"; OString "format"; OString "iface"; OString "name"; OString "label"; OString "protocol"; OStringList "server"; OString "username"; OString "secret"; OString "cachemode"; OString "discard"; OBool "copyonread"; OString "query"]; once_had_no_optargs = true; blocking = false; fish_alias = ["add"]; diff --git a/src/drives.c b/src/drives.c index ad747ab..1e6c95d 100644 --- a/src/drives.c +++ b/src/drives.c @@ -744,9 +744,8 @@ guestfs_impl_add_drive_opts (guestfs_h *g, const char *filename, data.nr_servers = 0; data.servers = NULL; - data.exportname = filename; - data.readonly = optargs->bitmask & GUESTFS_ADD_DRIVE_OPTS_READONLY_BITMASK + data.readonly = optargs->bitmask & GUESTFS_ADD_DRIVE_OPTS_READONLY_BITMASK ? optargs->readonly : false; data.format = optargs->bitmask & GUESTFS_ADD_DRIVE_OPTS_FORMAT_BITMASK ? optargs->format : NULL; @@ -771,6 +770,25 @@ guestfs_impl_add_drive_opts (guestfs_h *g, const char *filename, data.cachemode = optargs->bitmask & GUESTFS_ADD_DRIVE_OPTS_CACHEMODE_BITMASK ? optargs->cachemode : NULL; + /* If http or https are being used then the full path should + * be the path + query string. + */ + char *fullPath = NULL; + if ((STREQ (protocol, "http") || STREQ (protocol, "https")) && + optargs->bitmask & GUESTFS_ADD_DRIVE_OPTS_QUERY_BITMASK ) { + + if (asprintf(&fullPath, "%s?%s", filename, optargs->query) != -1) { + data.exportname = fullPath; + } else { + error (g, _("path and query_string concatenation must not fail.")); + free_drive_servers (data.servers, data.nr_servers); + return -1; + } + + } else { + data.exportname = filename; + } + if (optargs->bitmask & GUESTFS_ADD_DRIVE_OPTS_DISCARD_BITMASK) { if (STREQ (optargs->discard, "disable")) data.discard = discard_disable; diff --git a/src/launch-direct.c b/src/launch-direct.c index ea67ec9..cb82f20 100644 --- a/src/launch-direct.c +++ b/src/launch-direct.c @@ -1224,7 +1224,7 @@ make_uri (guestfs_h *g, const char *scheme, const char *user, break; } - return (char *) xmlSaveUri (&uri); + return xmlURIUnescapeString((char *) xmlSaveUri (&uri), -1, NULL); } /* Useful function to format a drive + protocol for qemu. Also shared -- 1.9.1