// -------------------------------------------------------- // Convenience Functions for UgUri gchar* ug_uri_get_user (UgUri* upart) { const char* str = NULL; int len; if ((len = ug_uri_part_user (upart, &str)) != 0) return g_strndup (str, len); return NULL; }
int ug_uri_part_password (UgUri* uuri, const char** password) { const char* tmp; int length; length = ug_uri_part_user (uuri, &tmp); if (length && tmp[length] == ':') { tmp += length + 1; // + ':' if (password) *password = tmp; return uuri->host - (tmp - uuri->uri) - 1; // - '@' } return 0; }
void ug_download_complete_data (UgDataset* dataset) { UgUri uripart; UgetCommon* common; const gchar* string; guint length; common = UG_DATASET_COMMON (dataset); if (common == NULL) return; if (ug_uri_init (&uripart, common->url) == 0) return; // file // if (common->file == NULL) { // string = ug_uri_get_file (&uripart); // if (string) // common->file = (gchar*) string; // else // common->file = g_strdup ("index.htm"); // } // user if (common->user == NULL) { length = ug_uri_part_user (&uripart, &string); if (length) common->password = g_strndup (string, length); } // password if (common->password == NULL) { length = ug_uri_part_password (&uripart, &string); if (length) common->password = g_strndup (string, length); } // Remove user & password from URL if (uripart.authority != uripart.host) { memmove ((char*)uripart.uri + uripart.authority, uripart.uri + uripart.host, strlen (uripart.uri + uripart.host) + 1); } }
int ug_uri_init (UgUri* upart, const char* uri) { const char* cur; const char* tmp; // scheme #if defined _WIN32 || defined _WIN64 cur = strpbrk (uri, ":\\/?#"); // make sure ':' before '/', '?', and '#' #else cur = strpbrk (uri, ":/?#"); // make sure ':' before '/', '?', and '#' #endif if (cur && cur[0] == ':') { if (upart == NULL) return cur - uri; upart->scheme_len = cur - uri; cur++; } else { if (upart == NULL) return 0; upart->scheme_len = 0; cur = uri; } upart->uri = uri; #if defined _WIN32 || defined _WIN64 // Windows Path if (upart->scheme_len == 1) { upart->scheme_len = 0; cur = uri; } #endif // _WIN32 || _WIN64 // authority & path if (upart->scheme_len && cur[0] == '/' && cur[1] == '/') { cur += 2; upart->authority = cur - uri; cur += strcspn (cur, "/"); } else upart->authority = -1; upart->path = cur - uri; // file upart->file = -1; if (cur[0]) { for (; ; ) { #if defined _WIN32 || defined _WIN64 tmp = strpbrk (cur, "\\/?#"); if (tmp == NULL || (tmp[0] != '/' && tmp[0] != '\\')) { #else tmp = strpbrk (cur, "/?#"); if (tmp == NULL || tmp[0] != '/') { #endif // _WIN32 || _WIN64 upart->file = cur - uri; break; } cur = tmp + 1; } } // query if ((tmp = strchr (cur, '?')) == NULL) upart->query = -1; else { cur = tmp + 1; upart->query = cur - uri; } // fragment if ((tmp = strrchr (cur, '#')) == NULL) upart->fragment = -1; else { cur = tmp + 1; upart->fragment = cur - uri; } // host & port upart->port = -1; if (upart->authority == -1) upart->host = -1; else { upart->host = upart->authority; tmp = uri + upart->authority; for (cur = uri + upart->path -1; cur >= tmp; cur--) { if (cur[0] == '@') { upart->host = cur - uri + 1; break; } if (cur[0] == ':') upart->port = cur - uri + 1; } } return upart->scheme_len; } int ug_uri_part_scheme (UgUri* uuri, const char** scheme) { if (scheme && uuri->scheme_len) *scheme = uuri->uri; return uuri->scheme_len; } int ug_uri_part_file (UgUri* uuri, const char** file) { if (uuri->file != -1) { if (file) *file = uuri->uri + uuri->file; if (uuri->query != -1) return uuri->query - uuri->file - 1; // - '?' if (uuri->fragment != -1) return uuri->fragment - uuri->file - 1; // - '#' return strlen (uuri->uri + uuri->file); } return 0; } int ug_uri_part_file_ext (UgUri* uuri, const char** ext) { const char* beg; const char* end; int len; if (uuri->file != -1) { len = ug_uri_part_file (uuri, &beg); end = uuri->uri + uuri->file + len -1; for (; end >= beg; end--) { if (end[0] == '.') { end += 1; // + '.' if (ext) *ext = end; return len - (end - beg); } } } return 0; } int ug_uri_part_query (UgUri* uuri, const char** query) { if (uuri->query != -1) { if (query) *query = uuri->uri + uuri->query; if (uuri->fragment != -1) return uuri->fragment - uuri->query -1; // - '#' return strlen (uuri->uri + uuri->query); } return 0; } int ug_uri_part_fragment (UgUri* uuri, const char** fragment) { if (uuri->fragment != -1) { if (fragment) *fragment = uuri->uri + uuri->fragment; return strlen (uuri->uri + uuri->fragment); } return 0; } int ug_uri_part_referrer (UgUri* uuri, const char** referrer) { if (referrer) *referrer = uuri->uri; if (uuri->file == -1) return uuri->path; return uuri->file; } int ug_uri_part_user (UgUri* uuri, const char** user) { const char* beg; const char* end; if (uuri->authority == uuri->host) return 0; beg = uuri->uri + uuri->authority; end = uuri->uri + uuri->host - 1; // - '@' if (user) *user = beg; for (; beg < end; beg++) { if (beg[0] == ':') break; } return beg - uuri->uri - uuri->authority; } int ug_uri_part_password (UgUri* uuri, const char** password) { const char* tmp; int length; length = ug_uri_part_user (uuri, &tmp); if (length && tmp[length] == ':') { tmp += length + 1; // + ':' if (password) *password = tmp; return uuri->host - (tmp - uuri->uri) - 1; // - '@' } return 0; } int ug_uri_part_host (UgUri* uuri, const char** host) { if (uuri->host != -1) { if (host) *host = uuri->uri + uuri->host; if (uuri->port != -1) return uuri->port - uuri->host - 1; // - ':' else return uuri->path - uuri->host; } return 0; } int ug_uri_part_port (UgUri* uuri, const char** port) { if (uuri->port != -1) { if (port) *port = uuri->uri + uuri->port; return uuri->path - uuri->port; } return 0; } int ug_uri_get_port (UgUri* uuri) { if (uuri->port != -1) return strtol (uuri->uri + uuri->port, NULL, 10); return -1; } char* ug_uri_get_file (UgUri* uuri) { const char* str; char* name; int len; len = ug_uri_part_file (uuri, &str); if (len == 0) return NULL; name = ug_unescape_uri (str, len); if (ug_utf8_get_invalid ((uint8_t*) name, NULL) == -1) return name; ug_free (name); return ug_strndup (str, len); } // ------------------------------------ // match uri functions int ug_uri_match_hosts (UgUri* uuri, char** hosts) { const char* str; const char* end1; const char* end2; int len; int lenHost; int nthHost; len = ug_uri_part_host (uuri, &str); if (len) { for (nthHost = 0; *hosts; hosts++, nthHost++) { lenHost = strlen (*hosts); if (lenHost > len) continue; // compare host from head if (strncasecmp (uuri->uri, *hosts, len) == 0) return nthHost; // compare host from tail end1 = str + len -1; end2 = *hosts + lenHost -1; for (; lenHost > 0; lenHost--, end1--, end2--) { if (end1[0] != end2[0]) break; } if (lenHost == 0) return nthHost; } } return -1; } int ug_uri_match_schemes (UgUri* uuri, char** schemes) { int len; int index; len = ug_uri_part_scheme (uuri, NULL); if (len) { for (index = 0; *schemes; schemes++, index++) { if (strncasecmp (uuri->uri, *schemes, len) == 0) return index; } } return -1; }