Hi,
This patch adds a bunch of tests related to efreet_uri, and enabled
parsing of usernames/passwords/ports along with the rest of the uri
scheme. the encode itself has also been updated to support all of this.
I wasn't exactly sure why efreet_uri_encode didn't even return the
hostname. if a program can't handle such a valid uri, it's a program
bug, thus it shouldn't be a limit of the library.
Index: src/lib/efreet_uri.h
===================================================================
--- src/lib/efreet_uri.h (revision 40539)
+++ src/lib/efreet_uri.h (working copy)
@@ -24,7 +24,11 @@ struct Efreet_Uri
{
const char *protocol; /**< The protocol used (usually 'file')*/
const char *hostname; /**< The name of the host if any, or NULL */
+ const char *username; /**< The username, or NULL */
+ const char *password; /**< The password, or NULL */
const char *path; /**< The full file path whitout protocol nor host*/
+
+ int port; /**< The port, or 0 */
};
Index: src/lib/efreet_uri.c
===================================================================
--- src/lib/efreet_uri.c (revision 40539)
+++ src/lib/efreet_uri.c (working copy)
@@ -6,6 +6,7 @@
#include <stdio.h>
#include <string.h>
+#include <stdlib.h>
#include <ctype.h>
#include <limits.h>
@@ -17,6 +18,8 @@
# include <Evil.h>
#endif
+#include <Ecore_Str.h>
+
#include "Efreet.h"
#include "efreet_private.h"
@@ -33,15 +36,20 @@ efreet_uri_decode(const char *full_uri)
{
Efreet_Uri *uri;
const char *p;
- char protocol[64], hostname[_POSIX_HOST_NAME_MAX], path[PATH_MAX];
- int i = 0;
+ char protocol[64], hostname[_POSIX_HOST_NAME_MAX], path[PATH_MAX], buf[PATH_MAX],
+ username[_POSIX_HOST_NAME_MAX], password[_POSIX_HOST_NAME_MAX], port[6];
+ int i = 0, auth_limit = _POSIX_HOST_NAME_MAX * 3;
- /* An uri should be in the form <protocol>://<hostname>/<path> */
+ /* An uri should be in the form <protocol>://<authority>/<path> */
if (!strstr(full_uri, "://")) return NULL;
memset(protocol, 0, 64);
+ memset(username, 0, _POSIX_HOST_NAME_MAX);
+ memset(password, 0, _POSIX_HOST_NAME_MAX);
memset(hostname, 0, _POSIX_HOST_NAME_MAX);
+ memset(port, 0, 6);
memset(path, 0, PATH_MAX);
+ memset(buf, 0, PATH_MAX);
/* parse protocol */
p = full_uri;
@@ -49,13 +57,41 @@ efreet_uri_decode(const char *full_uri)
protocol[i] = *p;
protocol[i] = '\0';
- /* parse hostname */
+ /* parse authority */
p += 3;
if (*p != '/')
{
- for (i = 0; *p != '/' && *p != '\0' && i < _POSIX_HOST_NAME_MAX; p++, i++)
- hostname[i] = *p;
- hostname[i] = '\0';
+ for (i = 0; *p != '/' && *p != '\0' && i < auth_limit; p++, i++)
+ {
+ if (*p == ':')
+ {
+ memcpy(hostname, buf, _POSIX_HOST_NAME_MAX);
+ memset(buf, 0, PATH_MAX);
+ i = -1;
+ }
+ else if (*p == '@')
+ {
+ /* the previous segment is the password */
+ if (hostname[0] != '\0')
+ {
+ memcpy(username, hostname, _POSIX_HOST_NAME_MAX);
+ memcpy(password, buf, _POSIX_HOST_NAME_MAX);
+ memset(hostname, 0, _POSIX_HOST_NAME_MAX);
+ }
+ else
+ memcpy(username, buf, _POSIX_HOST_NAME_MAX);
+ memset(buf, 0, PATH_MAX);
+ i = -1;
+ }
+ else
+ buf[i] = *p;
+ }
+ buf[i] = '\0';
+ /* the previous segment is the port */
+ if (hostname[0] != '\0')
+ memcpy(port, buf, 6);
+ else
+ memcpy(hostname, buf, _POSIX_HOST_NAME_MAX);
}
else
hostname[0] = '\0';
@@ -79,7 +115,10 @@ efreet_uri_decode(const char *full_uri)
if (!uri) return NULL;
uri->protocol = eina_stringshare_add(protocol);
+ uri->username = eina_stringshare_add(username);
+ uri->password = eina_stringshare_add(password);
uri->hostname = eina_stringshare_add(hostname);
+ uri->port = atoi(port);
uri->path = eina_stringshare_add(path);
return uri;
@@ -91,23 +130,46 @@ efreet_uri_decode(const char *full_uri)
* @brief Get the string rapresentation of the given uri struct escaping
* illegal caracters. Remember to free the string with eina_stringshare_del()
* when you don't need it anymore.
- * @note The resulting string will contain the protocol and the path but not
- * the hostname, as many apps doesn't handle it.
*/
EAPI const char *
efreet_uri_encode(Efreet_Uri *uri)
{
char dest[PATH_MAX * 3 + 4];
+ int full_size = PATH_MAX * 3 + 4;
const char *p;
int i;
if (!uri || !uri->path || !uri->protocol) return NULL;
- memset(dest, 0, PATH_MAX * 3 + 4);
+ memset(dest, 0, full_size);
snprintf(dest, strlen(uri->protocol) + 4, "%s://", uri->protocol);
- /* Most app doesn't handle the hostname in the uri so it's put to NULL */
- for (i = strlen(uri->protocol) + 3, p = uri->path; *p != '\0'; p++, i++)
+ if (*uri->username != '\0')
{
+ ecore_strlcat(dest, uri->username, full_size);
+ if (*uri->password != '\0')
+ {
+ const char *buf[_POSIX_HOST_NAME_MAX];
+
+ snprintf(buf, sizeof(buf), ":%s", uri->password);
+ ecore_strlcat(dest, buf, full_size);
+ }
+ ecore_strlcat(dest, "@", full_size);
+ }
+
+ if (*uri->hostname != '\0')
+ {
+ ecore_strlcat(dest, uri->hostname, full_size);
+ if (uri->port)
+ {
+ const char *buf[_POSIX_HOST_NAME_MAX];
+
+ snprintf(buf, sizeof(buf), ":%d", uri->port);
+ ecore_strlcat(dest, buf, full_size);
+ }
+ }
+
+ for (i = strlen(dest), p = uri->path; *p != '\0'; p++, i++)
+ {
if (isalnum(*p) || strchr("/$-_.+!*'()", *p))
dest[i] = *p;
else
@@ -129,7 +191,9 @@ efreet_uri_free(Efreet_Uri *uri)
{
if (!uri) return;
IF_RELEASE(uri->protocol);
+ IF_RELEASE(uri->username);
+ IF_RELEASE(uri->password);
+ IF_RELEASE(uri->hostname);
IF_RELEASE(uri->path);
- IF_RELEASE(uri->hostname);
FREE(uri);
}
Index: src/bin/ef_uri.c
===================================================================
--- src/bin/ef_uri.c (revision 0)
+++ src/bin/ef_uri.c (revision 0)
@@ -0,0 +1,334 @@
+/* vim: set sw=4 ts=4 sts=4 et: */
+#include "Efreet.h"
+#include "efreet_private.h"
+#include <stdio.h>
+
+#define ERR(...) EINA_ERROR_PERR(__VA_ARGS__)
+
+int
+ef_cb_uri_decode(void)
+{
+ Efreet_Uri *uri;
+ const char *full_uri = "file:///tmp/foo/bar";
+
+ printf("\n");
+
+ uri = efreet_uri_decode(full_uri);
+
+ if (!uri->protocol || *uri->protocol == '\0')
+ {
+ ERR("No protocol obtained from uri: %s\n", full_uri);
+ return 0;
+ }
+
+ if (strcmp(uri->protocol, "file"))
+ {
+ ERR("Protocol mismatch, expected 'file', got '%s'\n", uri->protocol);
+ return 0;
+ }
+
+ if (!uri->path || *uri->path == '\0')
+ {
+ ERR("No path obtained from uri: %s\n", full_uri);
+ return 0;
+ }
+
+ if (strcmp(uri->path, "/tmp/foo/bar"))
+ {
+ ERR("Path mismatch, expected '/tmp/foo/bar', got '%s'\n", uri->path);
+ return 0;
+ }
+
+ if (uri->hostname && *uri->hostname != '\0')
+ {
+ ERR("Hostname '%s', obtained from uri: %s\n", uri->hostname, full_uri);
+ return 0;
+ }
+
+ if (uri->username && *uri->username != '\0')
+ {
+ ERR("Username '%s' obtained from uri: %s\n", uri->username, full_uri);
+ return 0;
+ }
+
+ if (uri->password && *uri->password != '\0')
+ {
+ ERR("Password '%s' obtained from uri: %s\n", uri->password, full_uri);
+ return 0;
+ }
+
+ if (uri->port)
+ {
+ ERR("Port '%d' obtained from uri: %s\n", uri->port, full_uri);
+ return 0;
+ }
+
+ efreet_uri_free(uri);
+
+ uri = efreet_uri_decode("ftp://foo:[email protected]:123/alpha/beta");
+
+ if (strcmp(uri->protocol, "ftp"))
+ {
+ ERR("Protocol mismatch, expected 'ftp', got '%s'\n", uri->protocol);
+ return 0;
+ }
+
+ if (strcmp(uri->username, "foo"))
+ {
+ ERR("Username mismatch, expected 'foo', got '%s'\n", uri->username);
+ return 0;
+ }
+
+ if (strcmp(uri->password, "bar"))
+ {
+ ERR("Password mismatch, expected 'bar', got '%s'\n", uri->password);
+ return 0;
+ }
+
+ if (strcmp(uri->hostname, "example.com"))
+ {
+ ERR("Hostname mismatch, expected 'example.com', got '%s'\n", uri->hostname);
+ return 0;
+ }
+
+ if (uri->port != 123)
+ {
+ ERR("Port mismatch, expected '123', got '%d'\n", uri->port);
+ return 0;
+ }
+
+ if (strcmp(uri->path, "/alpha/beta"))
+ {
+ ERR("Path mismatch, expected '/alpha/beta', got '%s'\n", uri->path);
+ return 0;
+ }
+
+
+ efreet_uri_free(uri);
+
+ uri = efreet_uri_decode("ftp://[email protected]:123");
+
+ if (strcmp(uri->protocol, "ftp"))
+ {
+ ERR("Protocol mismatch, expected 'ftp', got '%s'\n", uri->protocol);
+ return 0;
+ }
+
+ if (strcmp(uri->username, "foo"))
+ {
+ ERR("Username mismatch, expected 'foo', got '%s'\n", uri->username);
+ return 0;
+ }
+
+ if (*uri->password != '\0')
+ {
+ ERR("Password mismatch, expected '', got '%s'\n", uri->password);
+ return 0;
+ }
+
+ if (strcmp(uri->hostname, "example.com"))
+ {
+ ERR("Hostname mismatch, expected 'example.com', got '%s'\n", uri->hostname);
+ return 0;
+ }
+
+ if (uri->port != 123)
+ {
+ ERR("Port mismatch, expected '123', got '%d'\n", uri->port);
+ return 0;
+ }
+
+ if (*uri->path != '\0')
+ {
+ ERR("Path mismatch, expected '', got '%s'\n", uri->path);
+ return 0;
+ }
+
+ uri = efreet_uri_decode("ftp://[email protected]");
+
+ if (strcmp(uri->protocol, "ftp"))
+ {
+ ERR("Protocol mismatch, expected 'ftp', got '%s'\n", uri->protocol);
+ return 0;
+ }
+
+ if (strcmp(uri->username, "foo"))
+ {
+ ERR("Username mismatch, expected 'foo', got '%s'\n", uri->username);
+ return 0;
+ }
+
+ if (*uri->password != '\0')
+ {
+ ERR("Password mismatch, expected '', got '%s'\n", uri->password);
+ return 0;
+ }
+
+ if (strcmp(uri->hostname, "example.com"))
+ {
+ ERR("Hostname mismatch, expected 'example.com', got '%s'\n", uri->hostname);
+ return 0;
+ }
+
+ if (uri->port)
+ {
+ ERR("Port mismatch, expected '0', got '%d'\n", uri->port);
+ return 0;
+ }
+
+ if (*uri->path != '\0')
+ {
+ ERR("Path mismatch, expected '', got '%s'\n", uri->path);
+ return 0;
+ }
+
+ efreet_uri_free(uri);
+
+ uri = efreet_uri_decode("ftp://example.com:123");
+
+ if (strcmp(uri->protocol, "ftp"))
+ {
+ ERR("Protocol mismatch, expected 'ftp', got '%s'\n", uri->protocol);
+ return 0;
+ }
+
+ if (*uri->username != '\0')
+ {
+ ERR("Username mismatch, expected '', got '%s'\n", uri->username);
+ return 0;
+ }
+
+ if (*uri->password != '\0')
+ {
+ ERR("Password mismatch, expected '', got '%s'\n", uri->password);
+ return 0;
+ }
+
+ if (strcmp(uri->hostname, "example.com"))
+ {
+ ERR("Hostname mismatch, expected 'example.com', got '%s'\n", uri->hostname);
+ return 0;
+ }
+
+ if (uri->port != 123)
+ {
+ ERR("Port mismatch, expected '123', got '%d'\n", uri->port);
+ return 0;
+ }
+
+ if (*uri->path != '\0')
+ {
+ ERR("Path mismatch, expected '', got '%s'\n", uri->path);
+ return 0;
+ }
+
+ efreet_uri_free(uri);
+
+ uri = efreet_uri_decode("ftp://example.com");
+
+ if (strcmp(uri->protocol, "ftp"))
+ {
+ ERR("Protocol mismatch, expected 'ftp', got '%s'\n", uri->protocol);
+ return 0;
+ }
+
+ if (*uri->username != '\0')
+ {
+ ERR("Username mismatch, expected '', got '%s'\n", uri->username);
+ return 0;
+ }
+
+ if (*uri->password != '\0')
+ {
+ ERR("Password mismatch, expected '', got '%s'\n", uri->password);
+ return 0;
+ }
+
+ if (strcmp(uri->hostname, "example.com"))
+ {
+ ERR("Hostname mismatch, expected 'example.com', got '%s'\n", uri->hostname);
+ return 0;
+ }
+
+ if (uri->port)
+ {
+ ERR("Port mismatch, expected '0', got '%d'\n", uri->port);
+ return 0;
+ }
+
+ if (*uri->path != '\0')
+ {
+ ERR("Path mismatch, expected '', got '%s'\n", uri->path);
+ return 0;
+ }
+
+ efreet_uri_free(uri);
+
+ return 1;
+}
+
+int
+ef_cb_uri_encode(void)
+{
+ Efreet_Uri *uri;
+ const char *full_uri1 = "ftp://foo:[email protected]:123/alpha/beta",
+ *full_uri2 = "ftp://[email protected]:123/alpha/beta",
+ *full_uri3 = "ftp://[email protected]/alpha/beta",
+ *full_uri4 = "ftp://example.com",
+ *full_uri5 = "ftp://example.com:123/alpha",
+ *test;
+
+ printf("\n");
+
+ uri = efreet_uri_decode(full_uri1);
+ test = efreet_uri_encode(uri);
+ if (strcmp(full_uri1, test))
+ {
+ ERR("Decode mismatch, expected '%s', got '%s'\n", full_uri1, test);
+ return 0;
+ }
+ eina_stringshare_del(test);
+ efreet_uri_free(uri);
+
+ uri = efreet_uri_decode(full_uri2);
+ test = efreet_uri_encode(uri);
+ if (strcmp(full_uri2, test))
+ {
+ ERR("Decode mismatch, expected '%s', got '%s'\n", full_uri2, test);
+ return 0;
+ }
+ eina_stringshare_del(test);
+ efreet_uri_free(uri);
+
+ uri = efreet_uri_decode(full_uri3);
+ test = efreet_uri_encode(uri);
+ if (strcmp(full_uri3, test))
+ {
+ ERR("Decode mismatch, expected '%s', got '%s'\n", full_uri3, test);
+ return 0;
+ }
+ eina_stringshare_del(test);
+ efreet_uri_free(uri);
+
+ uri = efreet_uri_decode(full_uri4);
+ test = efreet_uri_encode(uri);
+ if (strcmp(full_uri4, test))
+ {
+ ERR("Decode mismatch, expected '%s', got '%s'\n", full_uri4, test);
+ return 0;
+ }
+ eina_stringshare_del(test);
+ efreet_uri_free(uri);
+
+ uri = efreet_uri_decode(full_uri5);
+ test = efreet_uri_encode(uri);
+ if (strcmp(full_uri5, test))
+ {
+ ERR("Decode mismatch, expected '%s', got '%s'\n", full_uri5, test);
+ return 0;
+ }
+ eina_stringshare_del(test);
+ efreet_uri_free(uri);
+
+ return 1;
+}
Index: src/bin/main.c
===================================================================
--- src/bin/main.c (revision 40539)
+++ src/bin/main.c (working copy)
@@ -34,6 +34,8 @@ int ef_cb_menu_save(void);
int ef_cb_menu_edit(void);
#endif
int ef_cb_utils(void);
+int ef_cb_uri_decode(void);
+int ef_cb_uri_encode(void);
int ef_mime_cb_get(void);
typedef struct Efreet_Test Efreet_Test;
@@ -72,6 +74,8 @@ static Efreet_Test tests[] = {
{"Menu Edit", ef_cb_menu_edit},
#endif
{"Utils", ef_cb_utils},
+ {"Uri Decode", ef_cb_uri_decode},
+ {"Uri Encode", ef_cb_uri_encode},
{"Mime", ef_mime_cb_get},
{NULL, NULL}
};
Index: src/bin/Makefile.am
===================================================================
--- src/bin/Makefile.am (revision 40539)
+++ src/bin/Makefile.am (working copy)
@@ -27,6 +27,7 @@ ef_utils.c \
ef_desktop.c \
ef_menu.c \
ef_mime.c \
+ef_uri.c \
main.c
if DEFAULT_VISIBILITY
------------------------------------------------------------------------------
The NEW KODAK i700 Series Scanners deliver under ANY circumstances! Your
production scanning environment may not be a perfect world - but thanks to
Kodak, there's a perfect scanner to get the job done! With the NEW KODAK i700
Series Scanner you'll get full speed at 300 dpi even with all image
processing features enabled. http://p.sf.net/sfu/kodak-com
_______________________________________________
enlightenment-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/enlightenment-devel