Join url implemented
This commit is contained in:
parent
691ea94549
commit
2ca1648ee2
167
lib/url.c
167
lib/url.c
|
@ -16,6 +16,7 @@ Url *urllib_init (void);
|
|||
void urllib_free (Url *url);
|
||||
int urllib_parse (Url *url, const char *url_string);
|
||||
void urllib_tostring (Url *url, char *dest);
|
||||
int urllib_join (Url *url, const char *path);
|
||||
|
||||
int
|
||||
main (int argc,
|
||||
|
@ -26,11 +27,19 @@ main (int argc,
|
|||
|
||||
url = urllib_init ();
|
||||
|
||||
if (argc >= 2)
|
||||
if (argc == 2)
|
||||
{
|
||||
if (urllib_parse (url, argv[1]))
|
||||
return 1;
|
||||
}
|
||||
if (argc >= 3)
|
||||
{
|
||||
if (urllib_parse (url, argv[1]))
|
||||
return 1;
|
||||
|
||||
if (urllib_join (url, argv[2]))
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
printf ("Enter a url : ");
|
||||
|
@ -38,6 +47,12 @@ main (int argc,
|
|||
|
||||
if (urllib_parse (url, url_str))
|
||||
return 1;
|
||||
|
||||
printf ("Enter a path : ");
|
||||
scanf ("%s", url_str);
|
||||
|
||||
if (urllib_join (url, url_str))
|
||||
return 1;
|
||||
}
|
||||
|
||||
urllib_tostring (url, url_str);
|
||||
|
@ -74,7 +89,6 @@ urllib_free (Url *url)
|
|||
free (url);
|
||||
}
|
||||
|
||||
/* check this parser : http://draft.scyphus.co.jp/lang/c/url_parser.html not perfect but could give ideas */
|
||||
int
|
||||
urllib_parse (Url *url,
|
||||
const char *url_string)
|
||||
|
@ -189,12 +203,11 @@ urllib_parse (Url *url,
|
|||
}
|
||||
|
||||
return 0;
|
||||
|
||||
//is there a path ? (test \0)
|
||||
}
|
||||
|
||||
void
|
||||
urllib_tostring (Url *url, char *dest)
|
||||
urllib_tostring (Url *url,
|
||||
char *dest)
|
||||
{
|
||||
if (url->port == NULL)
|
||||
if (url->path == NULL)
|
||||
|
@ -208,6 +221,144 @@ urllib_tostring (Url *url, char *dest)
|
|||
sprintf (dest, "%s://%s:%s%s\r\n", url->scheme, url->host, url->port, url->path);
|
||||
}
|
||||
|
||||
void
|
||||
urllib_join (Url *url, const char *path)
|
||||
{}
|
||||
int
|
||||
urllib_join (Url *url,
|
||||
const char *path)
|
||||
{// view RFC 3986, section 5.2.4
|
||||
int len = strlen (path);
|
||||
char *base, *result, *inputcursor;
|
||||
|
||||
if (len == 0)//nothing to merge
|
||||
return 0;
|
||||
|
||||
if (url->path == NULL)//no current path, path = '/'
|
||||
{
|
||||
url->path = malloc (sizeof (char) * 2);
|
||||
if (url->path == NULL)
|
||||
return 1;
|
||||
|
||||
url->path[0] = '/';
|
||||
url->path[1] = '\0';
|
||||
}
|
||||
|
||||
if (path[0] != '/') //relative path
|
||||
{
|
||||
int url_path_len = strlen (path);
|
||||
|
||||
if (url->path[url_path_len - 1] != '/')//we are on a file
|
||||
{
|
||||
char *tmpcursor = strrchr (url->path, '/');
|
||||
if (tmpcursor == NULL)
|
||||
return -1;
|
||||
|
||||
tmpcursor[1] = '\0';
|
||||
}
|
||||
|
||||
len += url_path_len;
|
||||
base = malloc (sizeof (char) * (len + 1));
|
||||
if (base == NULL)
|
||||
return 1;
|
||||
result = malloc (sizeof (char) * (len + 1));
|
||||
if (result == NULL)
|
||||
{
|
||||
free (base);
|
||||
return 1;
|
||||
}
|
||||
|
||||
sprintf (base, "%s%s", url->path, path);
|
||||
result[0] = '\0';
|
||||
}
|
||||
else //absolute path
|
||||
{
|
||||
base = malloc (sizeof (char) * (len + 1));
|
||||
if (base == NULL)
|
||||
return 1;
|
||||
result = malloc (sizeof (char) * (len + 1));
|
||||
if (result == NULL)
|
||||
{
|
||||
free (base);
|
||||
return 1;
|
||||
}
|
||||
|
||||
strncpy (base, path, len);
|
||||
base[len] = '\0';
|
||||
result[0] = '\0';
|
||||
}
|
||||
|
||||
inputcursor = base;
|
||||
len = strlen (inputcursor);
|
||||
while (len > 0) //while input buffer is not empty
|
||||
{
|
||||
char *tmpcursor;
|
||||
|
||||
if (len >= 3 && inputcursor[0] == '.' && inputcursor[1] == '.' && inputcursor[2] == '/')
|
||||
{
|
||||
inputcursor += 3;
|
||||
len = strlen (inputcursor);
|
||||
}
|
||||
else if (len >= 2 && inputcursor[0] == '.' && inputcursor[1] == '/')
|
||||
{
|
||||
inputcursor += 2;
|
||||
len = strlen (inputcursor);
|
||||
}
|
||||
else if (len >= 3 && inputcursor[0] == '/' && inputcursor[1] == '.' && inputcursor[2] == '/')
|
||||
{
|
||||
inputcursor += 2;
|
||||
len = strlen (inputcursor);
|
||||
}
|
||||
else if (len == 2 && inputcursor[0] == '/' && inputcursor[1] == '.')
|
||||
{
|
||||
inputcursor += 1;
|
||||
inputcursor[0] = '/';
|
||||
len = strlen (inputcursor);
|
||||
}
|
||||
else if (len >= 4 && inputcursor[0] == '/' && inputcursor[1] == '.' && inputcursor[2] == '.' && inputcursor[3] == '/')
|
||||
{
|
||||
inputcursor += 3;
|
||||
len = strlen (inputcursor);
|
||||
//remove result last segment
|
||||
tmpcursor = strrchr (result, '/');
|
||||
if (tmpcursor != NULL)
|
||||
*tmpcursor = '\0';
|
||||
}
|
||||
else if (len == 3 && inputcursor[0] == '/' && inputcursor[1] == '.' && inputcursor[2] == '.')
|
||||
{
|
||||
inputcursor += 2;
|
||||
inputcursor[0] = '/';
|
||||
len = strlen (inputcursor);
|
||||
//remove result last segment
|
||||
tmpcursor = strrchr (result, '/');
|
||||
if (tmpcursor != NULL)
|
||||
*tmpcursor = '\0';
|
||||
}
|
||||
else if ((len == 2 && inputcursor[0] == '.' && inputcursor[1] == '.') || (len == 1 && inputcursor[0] == '.'))
|
||||
{
|
||||
inputcursor[0] = '\0';
|
||||
len = strlen (inputcursor);
|
||||
}
|
||||
else
|
||||
{
|
||||
//get first segment of inputcursor then append it to result and delete it
|
||||
tmpcursor = strchr (inputcursor + 1, '/');
|
||||
if (tmpcursor == NULL)//last segment in input buffer
|
||||
{
|
||||
sprintf (result, "%s%s", result, inputcursor);
|
||||
*inputcursor = '\0';
|
||||
}
|
||||
else
|
||||
{
|
||||
len = tmpcursor - inputcursor;
|
||||
strncpy (result + strlen (result), inputcursor, len);
|
||||
inputcursor = tmpcursor;
|
||||
}
|
||||
|
||||
len = strlen (inputcursor);
|
||||
}
|
||||
}
|
||||
|
||||
free (url->path);
|
||||
url->path = result;
|
||||
free (base);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue