gchar * cockpit_web_server_parse_cookie (GHashTable *headers, const gchar *name) { const gchar *header; const gchar *pos; const gchar *value; const gchar *end; gboolean at_start = TRUE; gchar *decoded; gint diff; gint offset; header = g_hash_table_lookup (headers, "Cookie"); if (!header) return NULL; for (;;) { pos = strstr (header, name); if (!pos) return NULL; if (pos != header) { diff = strlen (header) - strlen (pos); offset = 1; at_start = FALSE; while (offset < diff) { if (!g_ascii_isspace (*(pos - offset))) { at_start = *(pos - offset) == ';'; break; } offset++; } } pos += strlen (name); if (*pos == '=' && at_start) { value = pos + 1; end = strchr (value, ';'); if (end == NULL) end = value + strlen (value); decoded = g_uri_unescape_segment (value, end, NULL); if (!decoded) g_debug ("invalid cookie encoding"); return decoded; } else { at_start = FALSE; } header = pos; } }
static gboolean parse_cookie_pair (const gchar *header_value, gchar **out_cookie_name, gchar **out_cookie_value, GError **error) { gboolean ret = FALSE; const gchar *equals; const gchar *cookie_raw; gs_free gchar *ret_cookie_name = NULL; gs_free gchar *ret_cookie_value = NULL; equals = strchr (header_value, '='); if (!equals) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "Invalid cookie; missing '='"); goto out; } ret_cookie_name = g_strndup (header_value, equals - header_value); if (!validate_token (ret_cookie_name, error)) goto out; cookie_raw = equals + 1; ret_cookie_value = g_uri_unescape_segment (cookie_raw, NULL, NULL); ret = TRUE; *out_cookie_name = ret_cookie_name; ret_cookie_name = NULL; *out_cookie_value = ret_cookie_value; ret_cookie_value = NULL; out: return ret; }
gchar * gvfs_udisks2_utils_lookup_fstab_options_value (const gchar *fstab_options, const gchar *key) { gchar *ret = NULL; if (fstab_options != NULL) { const gchar *start; guint n; start = strstr (fstab_options, key); if (start != NULL) { start += strlen (key); for (n = 0; start[n] != ',' && start[n] != '\0'; n++) ; if (n == 0) ret = g_strdup (""); else if (n >= 1) ret = g_uri_unescape_segment (start, start + n, NULL); } } return ret; }
const char* req_path(req_t* req) { g_return_val_if_fail(req != NULL, NULL); if (!req->uri) { return NULL; } if (!req->path) { char *end = strchr(req->uri, '?'); req->path = g_uri_unescape_segment(req->uri, end, NULL); } return req->path; }
gchar * cockpit_web_server_parse_cookie (GHashTable *headers, const gchar *name) { const gchar *header; const gchar *pos; const gchar *value; const gchar *end; gchar *decoded; header = g_hash_table_lookup (headers, "Cookie"); if (!header) return NULL; for (;;) { pos = strstr (header, name); if (!pos || (pos != header && *(pos - 1) != ';' && !g_ascii_isspace (*(pos - 1)))) return NULL; pos += strlen (name); if (*pos == '=') { value = pos + 1; end = strchr (value, ';'); if (end == NULL) end = value + strlen (value); decoded = g_uri_unescape_segment (value, end, NULL); if (!decoded) g_debug ("invalid cookie encoding"); return decoded; } header = pos; } }
// -------------------------------------------------------- // Convenience Functions for UgUri gchar* ug_uri_get_file (UgUri* upart) { const char* str; char* name; int len; if ((len = ug_uri_part_file (upart, &str)) == 0) return NULL; name = g_uri_unescape_segment (str, str+len, NULL); if (name == NULL) name = g_strndup (str, len); // check encoding if (g_utf8_validate (name, -1, NULL) == FALSE) { str = g_locale_to_utf8 (name, -1, NULL, NULL, NULL); if (str == NULL) { str = g_uri_escape_string (name, G_URI_RESERVED_CHARS_ALLOWED_IN_PATH_ELEMENT, FALSE); } g_free (name); return (gchar*) str; } return name; }
/** * _fm_path_new_uri_root * @uri: the uri in the form scheme://user@host/remaining/path * @len: length of the uri * @remaining: retrive the remaining path * * This function create a root FmpPath element for scheme://user@host/, * and return the remaining part in @remaining. */ static FmPath *_fm_path_new_uri_root (const char *uri, int len, const char **remaining, gboolean need_unescape) { FmPath *path; char *buf; const char *uri_end = uri + len; const char *host; const char *host_end; char *unescaped_host = NULL; int scheme_len; int host_len; int flags; // A generic URI: scheme://user@host/remaining/path if (!g_ascii_isalpha (uri[0])) goto on_error; // find the ":" after scheme for (scheme_len = 1; scheme_len < len && uri [scheme_len] != ':';) { char ch = uri [scheme_len]; // valid scheme characters if (g_ascii_isalnum (ch) || ch == '+' || ch == '-' || ch == '.') ++scheme_len; // invalid URI else goto on_error; } // there is no : in the URI, it's invalid if (scheme_len == len) goto on_error; // now there should be // following :, or no slashes at all, such as mailto:[email protected] host = uri + scheme_len + 1; // skip the slashes while (*host == '/' && host < uri_end) ++host; flags = 0; host_len = 0; // file:/// if (scheme_len == 4 && g_ascii_strncasecmp (uri, "file", 4) == 0) { if (remaining) *remaining = host; return fm_path_ref (root_path); } // Trash Can... else if (scheme_len == 5 && g_ascii_strncasecmp (uri, "trash", 5) == 0) // trashed files are on local filesystems { if (remaining) *remaining = host; return fm_path_ref (trash_path); } // Computer... else if (scheme_len == 8 && g_ascii_strncasecmp (uri, "computer", 8) == 0) { flags |= FM_PATH_IS_COMPUTER | FM_PATH_IS_VIRTUAL; host_end = host; } // Network... else if (scheme_len == 7 && g_ascii_strncasecmp (uri, "network", 7) == 0) { flags |= FM_PATH_IS_VIRTUAL; host_end = host; } // Mailto... else if (scheme_len == 6 && g_ascii_strncasecmp (uri, "mailto", 6) == 0) { // is any special handling needed? if (remaining) *remaining = uri_end; if (need_unescape) { unescaped_host = g_uri_unescape_string (uri, NULL); path = _fm_path_new_internal (NULL, unescaped_host, strlen (unescaped_host), 0); g_free (unescaped_host); } else path = _fm_path_new_internal (NULL, uri, len, 0); return path; } // A normal remote URI... else { // now we're at username@hostname, the authenticaion part host_end = host; while (host_end < uri_end && *host_end != '/') // find the end of host name ++host_end; host_len = (host_end - host); if (scheme_len == 4 && g_ascii_strncasecmp (uri, "menu", 4) == 0) { if (host_len == 0) // fallback to applications { host = "Applications"; host_len = 12; if (remaining) *remaining = uri_end; return fm_path_ref (apps_root_path); } else if (host_len == 12 && strncmp (host, "Applications", 12) == 0) { if (remaining) *remaining = host_end; return fm_path_ref (apps_root_path); } flags |= (FM_PATH_IS_VIRTUAL | FM_PATH_IS_XDG_MENU); } if (need_unescape) { unescaped_host = g_uri_unescape_segment (host, host_end, NULL); host = unescaped_host; host_len = strlen (host); } } if (remaining) *remaining = host_end; // it's reasonable to have double slashes :// for URIs other than mailto: len = scheme_len + 3 + host_len + 1; path = _fm_path_alloc (NULL, len, flags); buf = path->name; memcpy (buf, uri, scheme_len); // the scheme buf += scheme_len; memcpy (buf, "://", 3); // :// buf += 3; if (host_len > 0) // host name { memcpy (buf, host, host_len); buf += host_len; } buf[0] = '/'; // the trailing / buf[1] = '\0'; g_free (unescaped_host); return path; on_error: // this is not a valid URI // FIXME_pcm: should we return root or NULL? if (remaining) *remaining = uri + len; return fm_path_ref (root_path); }
gboolean _g_dbus_address_parse_entry (const gchar *address_entry, gchar **out_transport_name, GHashTable **out_key_value_pairs, GError **error) { gboolean ret; GHashTable *key_value_pairs; gchar *transport_name; gchar **kv_pairs; const gchar *s; guint n; ret = FALSE; kv_pairs = NULL; transport_name = NULL; key_value_pairs = NULL; s = strchr (address_entry, ':'); if (s == NULL) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT, _("Address element '%s' does not contain a colon (:)"), address_entry); goto out; } transport_name = g_strndup (address_entry, s - address_entry); key_value_pairs = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); kv_pairs = g_strsplit (s + 1, ",", 0); for (n = 0; kv_pairs != NULL && kv_pairs[n] != NULL; n++) { const gchar *kv_pair = kv_pairs[n]; gchar *key; gchar *value; s = strchr (kv_pair, '='); if (s == NULL) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT, _("Key/Value pair %d, '%s', in address element '%s' does not contain an equal sign"), n, kv_pair, address_entry); goto out; } key = g_uri_unescape_segment (kv_pair, s, NULL); value = g_uri_unescape_segment (s + 1, kv_pair + strlen (kv_pair), NULL); if (key == NULL || value == NULL) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT, _("Error unescaping key or value in Key/Value pair %d, '%s', in address element '%s'"), n, kv_pair, address_entry); g_free (key); g_free (value); goto out; } g_hash_table_insert (key_value_pairs, key, value); } ret = TRUE; out: g_strfreev (kv_pairs); if (ret) { if (out_transport_name != NULL) *out_transport_name = transport_name; else g_free (transport_name); if (out_key_value_pairs != NULL) *out_key_value_pairs = key_value_pairs; else if (key_value_pairs != NULL) g_hash_table_unref (key_value_pairs); } else { g_free (transport_name); if (key_value_pairs != NULL) g_hash_table_unref (key_value_pairs); } return ret; }
int moloch_hp_cb_on_headers_complete (http_parser *parser) { HTTPInfo_t *http = parser->data; MolochSession_t *session = http->session; char tag[200]; char version[20]; #ifdef HTTPDEBUG LOG("HTTPDEBUG: which: %d code: %d method: %d", http->which, parser->status_code, parser->method); #endif int len = snprintf(version, sizeof(version), "%d.%d", parser->http_major, parser->http_minor); if (parser->status_code == 0) { #ifndef REMOVEOLD snprintf(tag, sizeof(tag), "http:method:%s", http_method_str(parser->method)); moloch_nids_add_tag(session, tag); #endif moloch_field_string_add(methodField, session, http_method_str(parser->method), -1, TRUE); moloch_field_string_add(verReqField, session, version, len, TRUE); } else { #ifndef REMOVEOLD snprintf(tag, sizeof(tag), "http:statuscode:%d", parser->status_code); moloch_nids_add_tag(session, tag); #endif moloch_field_int_add(statuscodeField, session, parser->status_code); moloch_field_string_add(verResField, session, version, len, TRUE); } if (http->inValue & (1 << http->which) && http->pos[http->which]) { http_add_value(session, http); } http->header[0][0] = http->header[1][0] = 0; if (http->urlString) { char *ch = http->urlString->str; while (*ch) { if (*ch < 32) { moloch_nids_add_tag(session, "http:control-char"); break; } ch++; } } if (http->cookieString && http->cookieString->str[0]) { char *start = http->cookieString->str; while (1) { while (isspace(*start)) start++; char *equal = strchr(start, '='); if (!equal) break; moloch_field_string_add(cookieKeyField, session, start, equal-start, TRUE); start = strchr(equal+1, ';'); if(!start) break; start++; } g_string_truncate(http->cookieString, 0); } if (http->authString && http->authString->str[0]) { moloch_http_parse_authorization(session, http->authString->str); g_string_truncate(http->authString, 0); } if (http->hostString) { g_string_ascii_down(http->hostString); } if (http->urlString && http->hostString) { char *colon = strchr(http->hostString->str+2, ':'); if (colon) { moloch_field_string_add(hostField, session, http->hostString->str+2, colon - http->hostString->str-2, TRUE); } else { moloch_field_string_add(hostField, session, http->hostString->str+2, http->hostString->len-2, TRUE); } char *question = strchr(http->urlString->str, '?'); if (question) { moloch_field_string_add(pathField, session, http->urlString->str, question - http->urlString->str, TRUE); char *start = question+1; char *ch; int field = keyField; for (ch = start; *ch; ch++) { if (*ch == '&') { if (ch != start && (config.parseQSValue || field == keyField)) { char *str = g_uri_unescape_segment(start, ch, NULL); if (!str) { moloch_field_string_add(field, session, start, ch-start, TRUE); } else if (!moloch_field_string_add(field, session, str, strlen(str), FALSE)) { g_free(str); } } start = ch+1; field = keyField; continue; } else if (*ch == '=') { if (ch != start && (config.parseQSValue || field == keyField)) { char *str = g_uri_unescape_segment(start, ch, NULL); if (!str) { moloch_field_string_add(field, session, start, ch-start, TRUE); } else if (!moloch_field_string_add(field, session, str, strlen(str), FALSE)) { g_free(str); } } start = ch+1; field = valueField; } } if (config.parseQSValue && field == valueField && ch > start) { char *str = g_uri_unescape_segment(start, ch, NULL); if (!str) { moloch_field_string_add(field, session, start, ch-start, TRUE); } else if (!moloch_field_string_add(field, session, str, strlen(str), FALSE)) { g_free(str); } } } else { moloch_field_string_add(pathField, session, http->urlString->str, http->urlString->len, TRUE); } if (http->urlString->str[0] != '/') { char *result = strstr(http->urlString->str, http->hostString->str+2); /* If the host header is in the first 8 bytes of url then just use the url */ if (result && result - http->urlString->str <= 8) { moloch_field_string_add(urlsField, session, http->urlString->str, http->urlString->len, FALSE); g_string_free(http->urlString, FALSE); g_string_free(http->hostString, TRUE); } else { /* Host header doesn't match the url */ g_string_append(http->hostString, ";"); g_string_append(http->hostString, http->urlString->str); moloch_field_string_add(urlsField, session, http->hostString->str, http->hostString->len, FALSE); g_string_free(http->urlString, TRUE); g_string_free(http->hostString, FALSE); } } else { /* Normal case, url starts with /, so no extra host in url */ g_string_append(http->hostString, http->urlString->str); moloch_field_string_add(urlsField, session, http->hostString->str, http->hostString->len, FALSE); g_string_free(http->urlString, TRUE); g_string_free(http->hostString, FALSE); } http->urlString = NULL; http->hostString = NULL; } else if (http->urlString) { moloch_field_string_add(urlsField, session, http->urlString->str, http->urlString->len, FALSE); g_string_free(http->urlString, FALSE); http->urlString = NULL; } else if (http->hostString) { char *colon = strchr(http->hostString->str+2, ':'); if (colon) { moloch_field_string_add(hostField, session, http->hostString->str+2, colon - http->hostString->str-2, TRUE); } else { moloch_field_string_add(hostField, session, http->hostString->str+2, http->hostString->len-2, TRUE); } g_string_free(http->hostString, TRUE); http->hostString = NULL; } moloch_nids_add_tag(session, "protocol:http"); moloch_nids_add_protocol(session, "http"); if (pluginsCbs & MOLOCH_PLUGIN_HP_OHC) moloch_plugins_cb_hp_ohc(session, parser); return 0; }
GDecodedUri * g_vfs_decode_uri (const char *uri) { GDecodedUri *decoded; const char *p, *in, *hier_part_start, *hier_part_end, *query_start, *fragment_start; char *out; char c; /* From RFC 3986 Decodes: * URI = scheme ":" hier-part [ "?" query ] [ "#" fragment ] */ p = uri; /* Decode scheme: scheme = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." ) */ if (!g_ascii_isalpha (*p)) return NULL; while (1) { c = *p++; if (c == ':') break; if (!(g_ascii_isalnum(c) || c == '+' || c == '-' || c == '.')) return NULL; } decoded = g_vfs_decoded_uri_new (); decoded->scheme = g_malloc (p - uri); out = decoded->scheme; for (in = uri; in < p - 1; in++) *out++ = g_ascii_tolower (*in); *out = 0; hier_part_start = p; query_start = strchr (p, '?'); if (query_start) { hier_part_end = query_start++; fragment_start = strchr (query_start, '#'); if (fragment_start) { decoded->query = g_strndup (query_start, fragment_start - query_start); decoded->fragment = g_strdup (fragment_start+1); } else { decoded->query = g_strdup (query_start); decoded->fragment = NULL; } } else { /* No query */ decoded->query = NULL; fragment_start = strchr (p, '#'); if (fragment_start) { hier_part_end = fragment_start++; decoded->fragment = g_strdup (fragment_start); } else { hier_part_end = p + strlen (p); decoded->fragment = NULL; } } /* 3: hier-part = "//" authority path-abempty / path-absolute / path-rootless / path-empty */ if (hier_part_start[0] == '/' && hier_part_start[1] == '/') { const char *authority_start, *authority_end; const char *userinfo_start, *userinfo_end; const char *host_start, *host_end; const char *port_start; authority_start = hier_part_start + 2; /* authority is always followed by / or nothing */ authority_end = memchr (authority_start, '/', hier_part_end - authority_start); if (authority_end == NULL) authority_end = hier_part_end; /* 3.2: authority = [ userinfo "@" ] host [ ":" port ] */ userinfo_end = memchr (authority_start, '@', authority_end - authority_start); if (userinfo_end) { userinfo_start = authority_start; decoded->userinfo = g_uri_unescape_segment (userinfo_start, userinfo_end, NULL); if (decoded->userinfo == NULL) { g_vfs_decoded_uri_free (decoded); return NULL; } host_start = userinfo_end + 1; } else host_start = authority_start; /* We should handle hostnames in brackets, as those are used by IPv6 URIs * See http://tools.ietf.org/html/rfc2732 */ if (*host_start == '[') { char *s; port_start = NULL; host_end = memchr (host_start, ']', authority_end - host_start); if (host_end == NULL) { g_vfs_decoded_uri_free (decoded); return NULL; } /* Look for the start of the port, * And we sure we don't have it start somewhere * in the path section */ s = (char *) host_end; while (1) { if (*s == '/') { port_start = NULL; break; } else if (*s == ':') { port_start = s; break; } else if (*s == '\0') { break; } s++; } } else { port_start = memchr (host_start, ':', authority_end - host_start); } if (port_start) { host_end = port_start++; decoded->port = atoi(port_start); } else { host_end = authority_end; decoded->port = -1; } decoded->host = g_uri_unescape_segment (host_start, host_end, NULL); hier_part_start = authority_end; } decoded->path = g_uri_unescape_segment (hier_part_start, hier_part_end, "/"); if (decoded->path == NULL) { g_vfs_decoded_uri_free (decoded); return NULL; } return decoded; }
int moloch_hp_cb_on_message_complete (http_parser *parser) { HTTPInfo_t *http = parser->data; MolochSession_t *session = http->session; #ifdef HTTPDEBUG LOG("HTTPDEBUG: which: %d", session->which); #endif if (pluginsCbs & MOLOCH_PLUGIN_HP_OMC) moloch_plugins_cb_hp_omc(session, parser); http->header[0][0] = http->header[1][0] = 0; if (http->urlString) { char *ch = http->urlString->str; while (*ch) { if (*ch < 32) { moloch_nids_add_tag(session, "http:control-char"); break; } ch++; } } if (http->hostString) { g_string_ascii_down(http->hostString); } if (http->urlString && http->hostString) { char *colon = strchr(http->hostString->str+2, ':'); if (colon) { moloch_field_string_add(hostField, session, http->hostString->str+2, colon - http->hostString->str-2, TRUE); } else { moloch_field_string_add(hostField, session, http->hostString->str+2, http->hostString->len-2, TRUE); } char *question = strchr(http->urlString->str, '?'); if (question) { moloch_field_string_add(pathField, session, http->urlString->str, question - http->urlString->str, TRUE); char *start = question+1; char *ch; int field = keyField; for (ch = start; *ch; ch++) { if (*ch == '&') { if (ch != start && (config.parseQSValue || field == keyField)) { char *str = g_uri_unescape_segment(start, ch, NULL); if (!str) { moloch_field_string_add(field, session, start, ch-start, TRUE); } else if (!moloch_field_string_add(field, session, str, strlen(str), FALSE)) { g_free(str); } } start = ch+1; field = keyField; continue; } else if (*ch == '=') { if (ch != start && (config.parseQSValue || field == keyField)) { char *str = g_uri_unescape_segment(start, ch, NULL); if (!str) { moloch_field_string_add(field, session, start, ch-start, TRUE); } else if (!moloch_field_string_add(field, session, str, strlen(str), FALSE)) { g_free(str); } } start = ch+1; field = valueField; } } if (config.parseQSValue && field == valueField && ch > start) { char *str = g_uri_unescape_segment(start, ch, NULL); if (!str) { moloch_field_string_add(field, session, start, ch-start, TRUE); } else if (!moloch_field_string_add(field, session, str, strlen(str), FALSE)) { g_free(str); } } } else { moloch_field_string_add(pathField, session, http->urlString->str, http->urlString->len, TRUE); } if (http->urlString->str[0] != '/') { char *result = strstr(http->urlString->str, http->hostString->str+2); /* If the host header is in the first 8 bytes of url then just use the url */ if (result && result - http->urlString->str <= 8) { moloch_field_string_add(urlsField, session, http->urlString->str, http->urlString->len, FALSE); g_string_free(http->urlString, FALSE); g_string_free(http->hostString, TRUE); } else { /* Host header doesn't match the url */ g_string_append(http->hostString, ";"); g_string_append(http->hostString, http->urlString->str); moloch_field_string_add(urlsField, session, http->hostString->str, http->hostString->len, FALSE); g_string_free(http->urlString, TRUE); g_string_free(http->hostString, FALSE); } } else { /* Normal case, url starts with /, so no extra host in url */ g_string_append(http->hostString, http->urlString->str); moloch_field_string_add(urlsField, session, http->hostString->str, http->hostString->len, FALSE); g_string_free(http->urlString, TRUE); g_string_free(http->hostString, FALSE); } moloch_nids_add_tag(session, "protocol:http"); moloch_nids_add_protocol(session, "http"); http->urlString = NULL; http->hostString = NULL; } else if (http->urlString) { moloch_field_string_add(urlsField, session, http->urlString->str, http->urlString->len, FALSE); g_string_free(http->urlString, FALSE); moloch_nids_add_tag(session, "protocol:http"); moloch_nids_add_protocol(session, "http"); http->urlString = NULL; } else if (http->hostString) { char *colon = strchr(http->hostString->str+2, ':'); if (colon) { moloch_field_string_add(hostField, session, http->hostString->str+2, colon - http->hostString->str-2, TRUE); } else { moloch_field_string_add(hostField, session, http->hostString->str+2, http->hostString->len-2, TRUE); } g_string_free(http->hostString, TRUE); http->hostString = NULL; } if (http->inBody & (1 << session->which)) { const char *md5 = g_checksum_get_string(http->checksum[session->which]); moloch_field_string_add(md5Field, session, (char*)md5, 32, TRUE); } return 0; }
/** * gedit_utils_decode_uri: * @uri: the uri to decode * @scheme: (out) (allow-none): return value pointer for the uri's * scheme (e.g. http, sftp, ...), or %NULL * @user: (out) (allow-none): return value pointer for the uri user info, or %NULL * @port: (out) (allow-none): return value pointer for the uri port, or %NULL * @host: (out) (allow-none): return value pointer for the uri host, or %NULL * @path: (out) (allow-none): return value pointer for the uri path, or %NULL * * Parse and break an uri apart in its individual components like the uri * scheme, user info, port, host and path. The return value pointer can be * %NULL to ignore certain parts of the uri. If the function returns %TRUE, then * all return value pointers should be freed using g_free * * Return value: %TRUE if the uri could be properly decoded, %FALSE otherwise. */ gboolean gedit_utils_decode_uri (const gchar *uri, gchar **scheme, gchar **user, gchar **host, gchar **port, gchar **path) { /* Largely copied from glib/gio/gdummyfile.c:_g_decode_uri. This * functionality should be in glib/gio, but for now we implement it * ourselves (see bug #546182) */ const char *p, *in, *hier_part_start, *hier_part_end; char *out; char c; /* From RFC 3986 Decodes: * URI = scheme ":" hier-part [ "?" query ] [ "#" fragment ] */ p = uri; null_ptr (scheme); null_ptr (user); null_ptr (port); null_ptr (host); null_ptr (path); /* Decode scheme: * scheme = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." ) */ if (!g_ascii_isalpha (*p)) return FALSE; while (1) { c = *p++; if (c == ':') break; if (!(g_ascii_isalnum(c) || c == '+' || c == '-' || c == '.')) { return FALSE; } } if (scheme) { *scheme = g_malloc (p - uri); out = *scheme; for (in = uri; in < p - 1; in++) { *out++ = g_ascii_tolower (*in); } *out = '\0'; } hier_part_start = p; hier_part_end = p + strlen (p); if (hier_part_start[0] == '/' && hier_part_start[1] == '/') { const char *authority_start, *authority_end; const char *userinfo_start, *userinfo_end; const char *host_start, *host_end; const char *port_start; authority_start = hier_part_start + 2; /* authority is always followed by / or nothing */ authority_end = memchr (authority_start, '/', hier_part_end - authority_start); if (authority_end == NULL) authority_end = hier_part_end; /* 3.2: * authority = [ userinfo "@" ] host [ ":" port ] */ userinfo_end = memchr (authority_start, '@', authority_end - authority_start); if (userinfo_end) { userinfo_start = authority_start; if (user) *user = g_uri_unescape_segment (userinfo_start, userinfo_end, NULL); if (user && *user == NULL) { if (scheme) g_free (*scheme); return FALSE; } host_start = userinfo_end + 1; } else { host_start = authority_start; } port_start = memchr (host_start, ':', authority_end - host_start); if (port_start) { host_end = port_start++; if (port) *port = g_strndup (port_start, authority_end - port_start); } else { host_end = authority_end; } if (host) *host = g_strndup (host_start, host_end - host_start); hier_part_start = authority_end; } if (path) *path = g_uri_unescape_segment (hier_part_start, hier_part_end, "/"); return TRUE; }
/** * gst_rtsp_url_parse: * @urlstr: the url string to parse * @url: (out): location to hold the result. * * Parse the RTSP @urlstr into a newly allocated #GstRTSPUrl. Free after usage * with gst_rtsp_url_free(). * * Returns: a #GstRTSPResult. */ GstRTSPResult gst_rtsp_url_parse (const gchar * urlstr, GstRTSPUrl ** url) { GstRTSPUrl *res; gchar *p, *delim, *at, *col; gchar *host_end = NULL; guint i; g_return_val_if_fail (urlstr != NULL, GST_RTSP_EINVAL); g_return_val_if_fail (url != NULL, GST_RTSP_EINVAL); res = g_new0 (GstRTSPUrl, 1); p = (gchar *) urlstr; col = strstr (p, "://"); if (col == NULL) goto invalid; for (i = 0; i < G_N_ELEMENTS (rtsp_schemes_map); i++) { if (g_ascii_strncasecmp (rtsp_schemes_map[i].scheme, p, col - p) == 0) { res->transports = rtsp_schemes_map[i].transports; p = col + 3; break; } } if (res->transports == GST_RTSP_LOWER_TRANS_UNKNOWN) goto invalid; delim = strpbrk (p, "/?"); at = strchr (p, '@'); if (at && delim && at > delim) at = NULL; if (at) { col = strchr (p, ':'); /* must have a ':' and it must be before the '@' */ if (col == NULL || col > at) goto invalid; res->user = g_uri_unescape_segment (p, col, NULL); col++; res->passwd = g_uri_unescape_segment (col, at, NULL); /* move to host */ p = at + 1; } if (*p == '[') { res->family = GST_RTSP_FAM_INET6; /* we have an IPv6 address in the URL, find the ending ] which must be * before any delimiter */ host_end = strchr (++p, ']'); if (!host_end || (delim && host_end >= delim)) goto invalid; /* a port specifier must follow the address immediately */ col = host_end[1] == ':' ? host_end + 1 : NULL; } else { res->family = GST_RTSP_FAM_INET; col = strchr (p, ':'); /* we have a ':' and a delimiter but the ':' is after the delimiter, it's * not really part of the hostname */ if (col && delim && col >= delim) col = NULL; host_end = col ? col : delim; } if (!host_end) res->host = g_strdup (p); else { res->host = g_strndup (p, host_end - p); if (col) { res->port = strtoul (col + 1, NULL, 10); } else { /* no port specified, set to 0. gst_rtsp_url_get_port() will return the * default port */ res->port = 0; } } p = delim; if (p && *p == '/') { delim = strchr (p, '?'); if (!delim) res->abspath = g_strdup (p); else res->abspath = g_strndup (p, delim - p); p = delim; } else { /* IQinVision IQeye 1080p fails if a path '/' is provided * and RTSP does not mandate that a non-zero-length path * must be used */ res->abspath = g_strdup (""); } if (p && *p == '?') res->query = g_strdup (p + 1); *url = res; return GST_RTSP_OK; /* ERRORS */ invalid: { gst_rtsp_url_free (res); return GST_RTSP_EINVAL; } }
int main (int argc, char *argv[]) { gchar *uri = "http:\\\\[email protected]"; gchar *res_str = ":\\"; char *p; char *q; char *escape_str; p = g_uri_parse_scheme(uri); if(p) { if(strcmp(p, "http")) { std_log(LOG_FILENAME_LINE,"g_uri_parse_scheme didnt work as expected"); assert_failed = 1; } free(p); } else { std_log(LOG_FILENAME_LINE,"g_uri_parse_scheme returnd NULL. errno = %d", errno); assert_failed = 1; } //escape the uri escape_str = g_uri_escape_string(uri, res_str, TRUE); if(escape_str) { std_log(LOG_FILENAME_LINE, "escape string %s", escape_str); //convert back only a segment q = g_uri_unescape_segment(escape_str, escape_str+16, NULL); if(q) { std_log(LOG_FILENAME_LINE, "unescape segment string %s", q); if(strcmp(q, "http:\\\\www.no!")) { std_log(LOG_FILENAME_LINE,"g_uri_unescape_segment didnt work as expected"); assert_failed = 1; } free(q); } else { std_log(LOG_FILENAME_LINE,"g_uri_unescape_segment returned NULL. errno = %d", errno); assert_failed = 1; } //convert back the whole string p = g_uri_unescape_string(escape_str, NULL); if(p) { std_log(LOG_FILENAME_LINE, "unescape string %s", p); //converted string should be same as original uri string if(strcmp(p, uri)) { std_log(LOG_FILENAME_LINE,"g_uri_unescape_string returned NULL"); assert_failed = 1; } free(p); } else { std_log(LOG_FILENAME_LINE,"g_uri_unescape_string returned NULL. errno = %d", errno); assert_failed = 1; } free(escape_str); } else { std_log(LOG_FILENAME_LINE,"g_uri_escape_string returned NULL. errno = %d", errno); assert_failed = 1; } if(assert_failed) std_log(LOG_FILENAME_LINE,"Test Failed"); else std_log(LOG_FILENAME_LINE,"Test Successful"); create_xml(0); return 0; }
/** * g_uri_unescape_string: * @escaped_string: an escaped string to be unescaped. * @illegal_characters: an optional string of illegal characters not to be allowed. * * Unescapes a whole escaped string. * * If any of the characters in @illegal_characters or the character zero appears * as an escaped character in @escaped_string then that is an error and %NULL * will be returned. This is useful it you want to avoid for instance having a * slash being expanded in an escaped path element, which might confuse pathname * handling. * * Returns: an unescaped version of @escaped_string. The returned string * should be freed when no longer needed. * * Since: 2.16 **/ char * g_uri_unescape_string (const char *escaped_string, const char *illegal_characters) { return g_uri_unescape_segment (escaped_string, NULL, illegal_characters); }
/* This or something equivalent will eventually go into glib/guri.h */ gboolean nautilus_uri_parse (const char *uri, char **host, guint16 *port, char **userinfo) { char *tmp_str; const char *start, *p; char c; g_return_val_if_fail (uri != NULL, FALSE); if (host) *host = NULL; if (port) *port = 0; if (userinfo) *userinfo = NULL; /* From RFC 3986 Decodes: * URI = scheme ":" hier-part [ "?" query ] [ "#" fragment ] * hier-part = "//" authority path-abempty * path-abempty = *( "/" segment ) * authority = [ userinfo "@" ] host [ ":" port ] */ /* Check we have a valid scheme */ tmp_str = g_uri_parse_scheme (uri); if (tmp_str == NULL) return FALSE; g_free (tmp_str); /* Decode hier-part: * hier-part = "//" authority path-abempty */ p = uri; start = strstr (p, "//"); if (start == NULL) return FALSE; start += 2; if (strchr (start, '@') != NULL) { /* Decode userinfo: * userinfo = *( unreserved / pct-encoded / sub-delims / ":" ) * unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~" * pct-encoded = "%" HEXDIG HEXDIG */ p = start; while (1) { c = *p++; if (c == '@') break; /* pct-encoded */ if (c == '%') { if (!(g_ascii_isxdigit (p[0]) || g_ascii_isxdigit (p[1]))) return FALSE; p++; continue; } /* unreserved / sub-delims / : */ if (!(g_ascii_isalnum (c) || strchr (G_URI_OTHER_UNRESERVED, c) || strchr (G_URI_RESERVED_CHARS_SUBCOMPONENT_DELIMITERS, c) || c == ':')) return FALSE; } if (userinfo) *userinfo = g_strndup (start, p - start - 1); start = p; } else { p = start; } /* decode host: * host = IP-literal / IPv4address / reg-name * reg-name = *( unreserved / pct-encoded / sub-delims ) */ /* If IPv6 or IPvFuture */ if (*p == '[') { start++; p++; while (1) { c = *p++; if (c == ']') break; /* unreserved / sub-delims */ if (!(g_ascii_isalnum (c) || strchr (G_URI_OTHER_UNRESERVED, c) || strchr (G_URI_RESERVED_CHARS_SUBCOMPONENT_DELIMITERS, c) || c == ':' || c == '.')) goto error; } } else { while (1) { c = *p++; if (c == ':' || c == '/' || c == '?' || c == '#' || c == '\0') break; /* pct-encoded */ if (c == '%') { if (!(g_ascii_isxdigit (p[0]) || g_ascii_isxdigit (p[1]))) goto error; p++; continue; } /* unreserved / sub-delims */ if (!(g_ascii_isalnum (c) || strchr (G_URI_OTHER_UNRESERVED, c) || strchr (G_URI_RESERVED_CHARS_SUBCOMPONENT_DELIMITERS, c))) goto error; } } if (host) *host = g_uri_unescape_segment (start, p - 1, NULL); if (c == ':') { /* Decode pot: * port = *DIGIT */ guint tmp = 0; while (1) { c = *p++; if (c == '/' || c == '?' || c == '#' || c == '\0') break; if (!g_ascii_isdigit (c)) goto error; tmp = (tmp * 10) + (c - '0'); if (tmp > 65535) goto error; } if (port) *port = (guint16) tmp; } return TRUE; error: if (host && *host) { g_free (*host); *host = NULL; } if (userinfo && *userinfo) { g_free (*userinfo); *userinfo = NULL; } return FALSE; }