2005-04-28 12:12:11 +00:00
|
|
|
#include "string.h"
|
|
|
|
#include "url.h"
|
|
|
|
|
|
|
|
/*
|
2005-04-28 13:20:02 +00:00
|
|
|
* Parse a URL string into its constituent parts.
|
2005-04-28 12:12:11 +00:00
|
|
|
*
|
2005-04-28 13:20:02 +00:00
|
|
|
* We accept URLs of the form
|
2005-04-28 12:12:11 +00:00
|
|
|
*
|
2005-04-28 13:20:02 +00:00
|
|
|
* [protocol://[host][:port]/]path/to/file
|
|
|
|
*
|
|
|
|
* We return true for success, 0 for failure (e.g. unknown protocol).
|
|
|
|
* The URL string will be modified by having NULs inserted after
|
|
|
|
* "protocol", "host" and "port". The original URL can be
|
|
|
|
* reconstructed by calling unparse_url.
|
2005-04-28 12:12:11 +00:00
|
|
|
*
|
|
|
|
*/
|
2005-04-28 13:20:02 +00:00
|
|
|
void parse_url ( struct url_info *info, char *url ) {
|
|
|
|
char *p;
|
2005-04-28 12:12:11 +00:00
|
|
|
|
2005-04-28 13:20:02 +00:00
|
|
|
/* Zero the structure */
|
|
|
|
memset ( info, 0, sizeof ( *info ) );
|
2005-04-28 12:12:11 +00:00
|
|
|
|
2005-04-28 13:20:02 +00:00
|
|
|
/* Search for a protocol delimiter */
|
|
|
|
for ( p = url ; *p ; p++ ) {
|
|
|
|
if ( memcmp ( p, "://", 3 ) != 0 )
|
|
|
|
continue;
|
|
|
|
|
|
|
|
/* URL has an explicit protocol */
|
|
|
|
info->protocol = url;
|
|
|
|
*p = '\0';
|
|
|
|
p += 3;
|
|
|
|
info->host = p;
|
|
|
|
|
|
|
|
/* Search for port or file delimiter */
|
|
|
|
for ( ; *p ; p++ ) {
|
|
|
|
if ( *p == ':' ) {
|
|
|
|
*p = '\0';
|
|
|
|
info->port = p + 1;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if ( *p == '/' ) {
|
|
|
|
*(p++) = '\0';
|
2005-04-28 12:12:11 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2005-04-28 13:20:02 +00:00
|
|
|
info->file = p;
|
|
|
|
return;
|
2005-04-28 12:12:11 +00:00
|
|
|
}
|
|
|
|
|
2005-04-28 13:20:02 +00:00
|
|
|
/* URL has no explicit protocol; is just a filename */
|
|
|
|
info->file = url;
|
2005-04-28 12:12:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2005-04-28 13:20:02 +00:00
|
|
|
* Restore a parsed URL to its original pristine form.
|
2005-04-28 12:12:11 +00:00
|
|
|
*
|
|
|
|
*/
|
2005-04-28 13:20:02 +00:00
|
|
|
char * unparse_url ( struct url_info *info ) {
|
|
|
|
if ( info->protocol ) {
|
|
|
|
/* URL had a protocol: fill in the deleted separators */
|
|
|
|
info->file[-1] = '/';
|
|
|
|
if ( info->port ) {
|
|
|
|
info->port[-1] = ':';
|
|
|
|
}
|
|
|
|
info->host[-3] = ':';
|
|
|
|
return info->protocol;
|
|
|
|
} else {
|
|
|
|
/* URL had no protocol; was just a filename */
|
|
|
|
return info->file;
|
|
|
|
}
|
2005-04-28 12:12:11 +00:00
|
|
|
}
|