[Spice-devel] [PATCH] Added initial connection url handling using the uriparser library for proper URI parsing and handling. Can handle port, tls-port and password for now.
Tiziano Müller
tiziano.mueller at stepping-stone.ch
Thu Dec 30 04:15:58 PST 2010
Question is whether we want another dependency in spicec or not.
On the other hand is URI processing not as trivial as it seems.
Maybe making it a configure flag?
For spice-gtk glib would provide similar routines to parse URI strings.
---
client/application.cpp | 61 ++++++++++++++++++++++++++++++++++++++++++++++++
client/application.h | 1 +
configure.ac | 19 +++++++++++++++
3 files changed, 81 insertions(+), 0 deletions(-)
diff --git a/client/application.cpp b/client/application.cpp
index d865e84..a9e86d1 100644
--- a/client/application.cpp
+++ b/client/application.cpp
@@ -53,6 +53,8 @@
#include <smartcard_channel.h>
#endif
+#include <uriparser/Uri.h>
+
#define STICKY_KEY_PIXMAP ALT_IMAGE_RES_ID
#define STICKY_KEY_TIMEOUT 750
@@ -2130,6 +2132,56 @@ bool Application::set_disabled_display_effects(CmdLineParser& parser, char *val,
return true;
}
+bool Application::parse_connection_uri(const char* uri, std::string& host, int& port, int& sport, std::string& password)
+{
+ UriParserStateA state;
+ UriUriA uri_object;
+
+ state.uri = &uri_object;
+
+ if (uriParseUriA(&state, uri) != URI_SUCCESS) {
+ uriFreeUriMembersA(&uri_object);
+ return false;
+ }
+
+ if ((uri_object.scheme.afterLast != uri_object.scheme.first + 5) ||
+ (strncmp(uri_object.scheme.first, "spice", 5) != 0)) {
+ uriFreeUriMembersA(&uri_object);
+ return false;
+ }
+
+ host.assign(uri_object.hostText.first, uri_object.hostText.afterLast);
+
+ UriQueryListA* queryList;
+ int itemCount;
+
+ if (uriDissectQueryMallocA(&queryList, &itemCount,
+ uri_object.query.first, uri_object.query.afterLast) != URI_SUCCESS) {
+ uriFreeUriMembersA(&uri_object);
+ return false;
+ }
+
+ for (UriQueryListA* i(queryList); i != NULL; i = i->next) {
+ if ((strcmp(i->key, "port") == 0) && (i->value != NULL)) {
+ port = str_to_port(i->value);
+ continue;
+ }
+ if ((strcmp(i->key, "tls-port") == 0) && (i->value != NULL)) {
+ sport = str_to_port(i->value);
+ continue;
+ }
+ if ((strcmp(i->key, "password") == 0) && (i->value != NULL)) {
+ password = i->value;
+ continue;
+ }
+ /* ignore all other parameters for now */
+ }
+
+ uriFreeQueryListA(queryList);
+ uriFreeUriMembersA(&uri_object);
+ return true;
+}
+
void Application::on_cmd_line_invalid_arg(const char* arg0, const char* what, const char* val)
{
Platform::term_printf("%s: invalid %s value %s\n", arg0, what, val);
@@ -2185,6 +2237,7 @@ bool Application::process_cmd_line(int argc, char** argv)
SPICE_OPT_HOST = CmdLineParser::OPTION_FIRST_AVILABLE,
SPICE_OPT_PORT,
SPICE_OPT_SPORT,
+ SPICE_OPT_URI,
SPICE_OPT_PASSWORD,
SPICE_OPT_FULL_SCREEN,
SPICE_OPT_SECURE_CHANNELS,
@@ -2225,6 +2278,7 @@ bool Application::process_cmd_line(int argc, char** argv)
parser.add(SPICE_OPT_HOST, "host", "spice server address", "host", true, 'h');
parser.add(SPICE_OPT_PORT, "port", "spice server port", "port", true, 'p');
parser.add(SPICE_OPT_SPORT, "secure-port", "spice server secure port", "port", true, 's');
+ parser.add(SPICE_OPT_URI, "uri", "spice uri", "uri", true);
parser.add(SPICE_OPT_SECURE_CHANNELS, "secure-channels",
"force secure connection on the specified channels", "channel",
true);
@@ -2301,6 +2355,13 @@ bool Application::process_cmd_line(int argc, char** argv)
}
break;
}
+ case SPICE_OPT_URI: {
+ if (parse_connection_uri(val, host, port, sport, password) == false) {
+ on_cmd_line_invalid_arg(argv[0], "uri", val);
+ return false;
+ }
+ break;
+ }
case SPICE_OPT_FULL_SCREEN:
if (val) {
if (strcmp(val, "auto-conf")) {
diff --git a/client/application.h b/client/application.h
index f9bbd53..f6ec524 100644
--- a/client/application.h
+++ b/client/application.h
@@ -289,6 +289,7 @@ private:
bool set_canvas_option(CmdLineParser& parser, char *val, const char* arg0);
bool set_disabled_display_effects(CmdLineParser& parser, char *val, const char* arg0,
DisplaySetting& disp_setting);
+ bool parse_connection_uri(const char* uri, std::string& host, int& port, int& sport, std::string& password);
void on_cmd_line_invalid_arg(const char* arg0, const char* what, const char* val);
bool process_cmd_line(int argc, char** argv);
void register_channels();
diff --git a/configure.ac b/configure.ac
index 511d94e..ef4d68e 100644
--- a/configure.ac
+++ b/configure.ac
@@ -297,6 +297,25 @@ AC_SUBST(JPEG_LIBS)
AC_CHECK_LIB(z, deflate, Z_LIBS='-lz', AC_MSG_ERROR([zlib not found]))
AC_SUBST(Z_LIBS)
+URIPARSER_MISSING="Please install uriparser 0.7.5 or later.
+ On a Debian-based system enter 'sudo apt-get install liburiparser-dev'."
+AC_CHECK_LIB(uriparser, uriParseUriA,, AC_MSG_ERROR(${URIPARSER_MISSING}))
+AC_CHECK_HEADER(uriparser/Uri.h,, AC_MSG_ERROR(${URIPARSER_MISSING}))
+
+URIPARSER_TOO_OLD="uriparser 0.7.5 or later is required, your copy is too old."
+AC_COMPILE_IFELSE([
+#include <uriparser/Uri.h>
+#if (defined(URI_VER_MAJOR) && defined(URI_VER_MINOR) && defined(URI_VER_RELEASE) \
+&& ((URI_VER_MAJOR > 0) \
+|| ((URI_VER_MAJOR == 0) && (URI_VER_MINOR > 7)) \
+|| ((URI_VER_MAJOR == 0) && (URI_VER_MINOR == 7) && (URI_VER_RELEASE >= 5)) \
+))
+/* FINE */
+#else
+# error uriparser not recent enough
+#endif
+],,AC_MSG_ERROR(${URIPARSER_TOO_OLD}))
+
dnl ===========================================================================
dnl check compiler flags
--
1.7.3.4
--
stepping stone GmbH
Neufeldstrasse 9
CH-3012 Bern
Telefon: +41 31 332 53 63
www.stepping-stone.ch
tiziano.mueller at stepping-stone.ch
More information about the Spice-devel
mailing list