url: add support for using escaped characters in the url.

We need to allow users to specify escaped characters as part of the 'path'
field of a URL.
For example, '?' is used to separate the part and the optional list of
arguments.
IF 'path' contains a '?' character then that must be escaped as %3F.
So that libnfs will be able to tell it apart from the '?' separator.

I.e.
nfs://127.0.0.1/my?path/?version=4
must be escaped as
nfs://127.0.0.1/my%3Fpath/?version=4
before passed to any of the URL parsing functions.

Signed-off-by: Ronnie Sahlberg <ronniesahlberg@gmail.com>
master
Ronnie Sahlberg 2021-09-01 08:17:23 +10:00
parent 820dc73e32
commit fca28fe112
2 changed files with 49 additions and 1 deletions

10
README
View File

@ -42,6 +42,16 @@ The basic syntax of these URLs is :
nfs://<server|ipv4|ipv6>[:<port>]/path[?arg=val[&arg=val]*]
Special characters in 'path' are escaped using %-hex-hex syntax.
For example '?' must be escaped if it occurs in a path as '?' is also used to
separate the path from the optional list of url arguments.
Example:
nfs://127.0.0.1/my?path/?version=4
must be escaped as
nfs://127.0.0.1/my%3Fpath/?version=4
Arguments supported by libnfs are :
tcp-syncnt=<int> : Number of SYNs to send during the session establish
before failing setting up the tcp connection to the

View File

@ -303,11 +303,25 @@ nfs_set_context_args(struct nfs_context *nfs, const char *arg, const char *val)
return 0;
}
static int
tohex(char ch)
{
if (ch >= '0' && ch <= '9') {
return ch - '0';
}
ch &= 0xDF;
if (ch >= 'A' && ch <= 'F') {
return ch - 'A' + 10;
}
return -1;
}
static struct nfs_url *
nfs_parse_url(struct nfs_context *nfs, const char *url, int dir, int incomplete)
{
struct nfs_url *urls;
char *strp, *flagsp, *strp2;
char *strp, *flagsp, *strp2, ch;
int tmp;
if (strncmp(url, "nfs://", 6)) {
nfs_set_error(nfs, "Invalid URL specified");
@ -328,6 +342,30 @@ nfs_parse_url(struct nfs_context *nfs, const char *url, int dir, int incomplete)
return NULL;
}
/* unescape all % hex hex characters */
strp = urls->server;
while (strp && *strp) {
strp = strchr(strp, '%');
if (strp == NULL) {
break;
}
tmp = tohex(strp[1]);
if (tmp < 0) {
strp++;
continue;
}
ch = (tmp & 0x0f) << 4;
tmp = tohex(strp[2]);
if (tmp < 0) {
strp++;
continue;
}
ch |= tmp & 0x0f;
*strp = ch;
strcpy(strp + 1, strp + 3);
strp++;
}
if (urls->server[0] == '/' || urls->server[0] == '\0' ||
urls->server[0] == '?') {
if (incomplete) {