summaryrefslogtreecommitdiff
path: root/ACE/websvcs
diff options
context:
space:
mode:
authorWilliam R. Otte <wotte@dre.vanderbilt.edu>2006-07-24 15:50:30 +0000
committerWilliam R. Otte <wotte@dre.vanderbilt.edu>2006-07-24 15:50:30 +0000
commitc44379cc7d9c7aa113989237ab0f56db12aa5219 (patch)
tree66a84b20d47f2269d8bdc6e0323f338763424d3a /ACE/websvcs
parent3aff90f4a822fcf5d902bbfbcc9fa931d6191a8c (diff)
downloadATCD-c44379cc7d9c7aa113989237ab0f56db12aa5219.tar.gz
Repo restructuring
Diffstat (limited to 'ACE/websvcs')
-rw-r--r--ACE/websvcs/Makefile.am14
-rw-r--r--ACE/websvcs/README11
-rw-r--r--ACE/websvcs/lib/Makefile.am36
-rw-r--r--ACE/websvcs/lib/URL_Addr.cpp967
-rw-r--r--ACE/websvcs/lib/URL_Addr.h404
-rw-r--r--ACE/websvcs/lib/URL_Addr.i155
-rw-r--r--ACE/websvcs/lib/lib.mpc11
-rw-r--r--ACE/websvcs/lib/websvcs_export.h44
-rw-r--r--ACE/websvcs/tests/Makefile.am34
-rw-r--r--ACE/websvcs/tests/Test_URL_Addr.cpp214
-rw-r--r--ACE/websvcs/tests/tests.mpc13
11 files changed, 1903 insertions, 0 deletions
diff --git a/ACE/websvcs/Makefile.am b/ACE/websvcs/Makefile.am
new file mode 100644
index 00000000000..be02feea0e1
--- /dev/null
+++ b/ACE/websvcs/Makefile.am
@@ -0,0 +1,14 @@
+## Process this file with automake to create Makefile.in
+##
+## $Id$
+##
+## This file was generated by MPC. Any changes made directly to
+## this file will be lost the next time it is generated.
+##
+## MPC Command:
+## /acebuilds/ACE_wrappers-repository/bin/mwc.pl -include /acebuilds/MPC/config -include /acebuilds/MPC/templates -feature_file /acebuilds/ACE_wrappers-repository/local.features -noreldefs -type automake -exclude build,Kokyu
+
+SUBDIRS = \
+ lib \
+ tests
+
diff --git a/ACE/websvcs/README b/ACE/websvcs/README
new file mode 100644
index 00000000000..4eec972c901
--- /dev/null
+++ b/ACE/websvcs/README
@@ -0,0 +1,11 @@
+# $Id$
+
+ This directory contains utility classes to build web clients
+and servers. At this point we have only implemented simple classes to
+manipulate and parse URL addresses, but hopefully the library will
+grow over time.
+
+Point of Contact: Carlos O'Ryan <coryan@cs.wustl.edu>
+
+
+
diff --git a/ACE/websvcs/lib/Makefile.am b/ACE/websvcs/lib/Makefile.am
new file mode 100644
index 00000000000..53b475708db
--- /dev/null
+++ b/ACE/websvcs/lib/Makefile.am
@@ -0,0 +1,36 @@
+## Process this file with automake to create Makefile.in
+##
+## $Id$
+##
+## This file was generated by MPC. Any changes made directly to
+## this file will be lost the next time it is generated.
+##
+## MPC Command:
+## /acebuilds/ACE_wrappers-repository/bin/mwc.pl -include /acebuilds/MPC/config -include /acebuilds/MPC/templates -feature_file /acebuilds/ACE_wrappers-repository/local.features -noreldefs -type automake -exclude build,Kokyu
+
+ACE_BUILDDIR = $(top_builddir)
+ACE_ROOT = $(top_srcdir)
+
+## Makefile.websvcs.am
+
+noinst_LTLIBRARIES = libwebsvcs.la
+
+libwebsvcs_la_CPPFLAGS = \
+ -I$(ACE_ROOT) \
+ -I$(ACE_BUILDDIR) \
+ -DACE_WEBSVCS_BUILD_DLL
+
+libwebsvcs_la_SOURCES = \
+ URL_Addr.cpp
+
+noinst_HEADERS = \
+ URL_Addr.h \
+ URL_Addr.i
+
+## Clean up template repositories, etc.
+clean-local:
+ -rm -f *~ *.bak *.rpo *.sym lib*.*_pure_* core core.*
+ -rm -f gcctemp.c gcctemp so_locations *.ics
+ -rm -rf cxx_repository ptrepository ti_files
+ -rm -rf templateregistry ir.out
+ -rm -rf ptrepository SunWS_cache Templates.DB
diff --git a/ACE/websvcs/lib/URL_Addr.cpp b/ACE/websvcs/lib/URL_Addr.cpp
new file mode 100644
index 00000000000..86a0a9d0cea
--- /dev/null
+++ b/ACE/websvcs/lib/URL_Addr.cpp
@@ -0,0 +1,967 @@
+// $Id$
+
+#include "URL_Addr.h"
+
+#if !defined (__ACE_INLINE__)
+#include "URL_Addr.i"
+#endif /* __ACE_INLINE__ */
+
+#include "ace/OS_Memory.h"
+#include "ace/OS_NS_strings.h"
+#include "ace/OS_NS_stdio.h"
+
+ACE_RCSID(ace, URL_Addr, "$Id$")
+
+static ACE_TCHAR http[] = ACE_TEXT ("http:");
+static size_t http_size = sizeof(http)/sizeof(http[0]) - 1;
+static ACE_TCHAR ftp[] = ACE_TEXT ("ftp:");
+static size_t ftp_size = sizeof(ftp)/sizeof(ftp[0]) - 1;
+static ACE_TCHAR mailto[] = ACE_TEXT ("mailto:");
+static size_t mailto_size = sizeof(mailto)/sizeof(mailto[0]) - 1;
+
+static ACE_TCHAR file[] = ACE_TEXT ("file:");
+static size_t file_size = sizeof(file)/sizeof(file[0]) - 1;
+static ACE_TCHAR afs[] = ACE_TEXT ("afs:");
+static size_t afs_size = sizeof(afs)/sizeof(afs[0]) - 1;
+static ACE_TCHAR news[] = ACE_TEXT ("news:");
+static size_t news_size = sizeof(news)/sizeof(news[0]) - 1;
+static ACE_TCHAR nntp[] = ACE_TEXT ("nntp:");
+static size_t nntp_size = sizeof(nntp)/sizeof(nntp[0]) - 1;
+static ACE_TCHAR cid[] = ACE_TEXT ("cid:");
+static size_t cid_size = sizeof(cid)/sizeof(cid[0]) - 1;
+static ACE_TCHAR mid[] = ACE_TEXT ("mid:");
+static size_t mid_size = sizeof(mid)/sizeof(mid[0]) - 1;
+static ACE_TCHAR wais[] = ACE_TEXT ("wais:");
+static size_t wais_size = sizeof(wais)/sizeof(wais[0]) - 1;
+static ACE_TCHAR prospero[] = ACE_TEXT ("prospero:");
+static size_t prospero_size = sizeof(prospero)/sizeof(prospero[0]) - 1;
+static ACE_TCHAR telnet[] = ACE_TEXT ("telnet:");
+static size_t telnet_size = sizeof(telnet)/sizeof(telnet[0]) - 1;
+static ACE_TCHAR rlogin[] = ACE_TEXT ("rlogin:");
+static size_t rlogin_size = sizeof(rlogin)/sizeof(rlogin[0]) - 1;
+static ACE_TCHAR tn3270[] = ACE_TEXT ("tn3270:");
+static size_t tn3270_size = sizeof(tn3270)/sizeof(tn3270[0]) - 1;
+static ACE_TCHAR gopher[] = ACE_TEXT ("gopher:");
+static size_t gopher_size = sizeof(gopher)/sizeof(gopher[0]) - 1;
+
+// When assembling URLs, sprintf() is often used. The format specifier for
+// a string changes depending on the platform and char width being fed to it.
+// Since we use ACE_TCHAR for strings, and it changes with the char width,
+// the printf specifier needs to change with the platform.
+#if defined (ACE_WIN32) || !defined (ACE_USES_WCHAR)
+# define ACE_PRINTF_S ACE_TEXT ("%s")
+#else
+# define ACE_PRINTF_S ACE_TEXT ("%ls")
+#endif
+
+ACE_URL_Addr::ACE_URL_Addr (void)
+ : url_ (0)
+{
+}
+
+ACE_URL_Addr::~ACE_URL_Addr ()
+{
+ ACE_OS::free (this->url_);
+ this->url_ = 0;
+}
+
+int
+ACE_URL_Addr::set (const ACE_URL_Addr& address)
+{
+ return this->ACE_URL_Addr::string_to_addr (address.url_);
+}
+
+int
+ACE_URL_Addr::string_to_addr (const ACE_TCHAR *address)
+{
+ if (this->url_ != 0)
+ ACE_OS::free (this->url_);
+ if (address == 0)
+ return -1;
+ ACE_ALLOCATOR_RETURN (this->url_, ACE_OS::strdup (address), -1);
+ return 0;
+}
+
+int
+ACE_URL_Addr::addr_to_string (ACE_TCHAR *s,
+ size_t size,
+ int) const
+{
+ if (size < ACE_OS::strlen (this->url_))
+ return -1;
+ ACE_OS::strcpy (s, this->url_);
+ return 0;
+}
+
+int
+ACE_URL_Addr::accept (ACE_URL_Addr_Visitor* visitor)
+{
+ return visitor->visit (this);
+}
+
+// The factory method to create URL addresses.
+ACE_URL_Addr*
+ACE_URL_Addr::create_address (const ACE_TCHAR *url)
+{
+ ACE_URL_Addr* addr = 0;
+ if (ACE_OS::strncasecmp (http, url, http_size) == 0)
+ ACE_NEW_RETURN (addr, ACE_HTTP_Addr (), 0);
+ else if (ACE_OS::strncasecmp (ftp, url, ftp_size) == 0)
+ ACE_NEW_RETURN (addr, ACE_FTP_Addr (), 0);
+ else if (ACE_OS::strncasecmp (mailto, url, mailto_size) == 0)
+ ACE_NEW_RETURN (addr, ACE_Mailto_Addr (), 0);
+ else
+ ACE_NEW_RETURN (addr, ACE_URL_Addr (), 0);
+
+ if (addr->string_to_addr (url) != 0)
+ {
+ delete addr;
+ addr = 0;
+ }
+ return addr;
+}
+
+int
+ACE_URL_Addr::known_scheme (const ACE_TCHAR *url)
+{
+ if (ACE_OS::strncasecmp (http, url, http_size) == 0)
+ return 1;
+ else if (ACE_OS::strncasecmp (ftp, url, ftp_size) == 0)
+ return 1;
+ else if (ACE_OS::strncasecmp (mailto, url, mailto_size) == 0)
+ return 1;
+ else if (ACE_OS::strncasecmp (file, url, file_size) == 0)
+ return 1;
+ else if (ACE_OS::strncasecmp (afs, url, afs_size) == 0)
+ return 1;
+ else if (ACE_OS::strncasecmp (news, url, news_size) == 0)
+ return 1;
+ else if (ACE_OS::strncasecmp (nntp, url, nntp_size) == 0)
+ return 1;
+ else if (ACE_OS::strncasecmp (cid, url, cid_size) == 0)
+ return 1;
+ else if (ACE_OS::strncasecmp (mid, url, mid_size) == 0)
+ return 1;
+ else if (ACE_OS::strncasecmp (wais, url, wais_size) == 0)
+ return 1;
+ else if (ACE_OS::strncasecmp (prospero, url, prospero_size) == 0)
+ return 1;
+ else if (ACE_OS::strncasecmp (telnet, url, telnet_size) == 0)
+ return 1;
+ else if (ACE_OS::strncasecmp (rlogin, url, rlogin_size) == 0)
+ return 1;
+ else if (ACE_OS::strncasecmp (tn3270, url, tn3270_size) == 0)
+ return 1;
+ else if (ACE_OS::strncasecmp (gopher, url, gopher_size) == 0)
+ return 1;
+
+ return 0;
+}
+
+// ****************************************************************
+
+ACE_URL_Addr_Visitor::~ACE_URL_Addr_Visitor (void)
+{
+}
+
+int
+ACE_URL_Addr_Visitor::visit (ACE_URL_Addr*)
+{
+ return 0;
+}
+
+int
+ACE_URL_Addr_Visitor::visit (ACE_HTTP_Addr*)
+{
+ return 0;
+}
+
+int
+ACE_URL_Addr_Visitor::visit (ACE_FTP_Addr*)
+{
+ return 0;
+}
+
+int
+ACE_URL_Addr_Visitor::visit (ACE_Mailto_Addr*)
+{
+ return 0;
+}
+
+// ****************************************************************
+
+ACE_HTTP_Addr::ACE_HTTP_Addr (void)
+ : hostname_ (0),
+ port_number_ (0),
+ path_ (0),
+ query_ (0)
+{
+}
+
+ACE_HTTP_Addr::ACE_HTTP_Addr (const ACE_TCHAR *host_name,
+ const ACE_TCHAR *path,
+ const ACE_TCHAR *query,
+ u_short port)
+ : hostname_ (0),
+ port_number_ (0),
+ path_ (0),
+ query_ (0)
+{
+ this->set (host_name, path, query, port);
+}
+
+ACE_HTTP_Addr::ACE_HTTP_Addr (const ACE_HTTP_Addr &addr)
+ : ACE_URL_Addr (),
+ hostname_ (0),
+ port_number_ (0),
+ path_ (0),
+ query_ (0)
+{
+ this->set (addr);
+}
+
+ACE_HTTP_Addr::~ACE_HTTP_Addr (void)
+{
+ this->clear ();
+ this->hostname_ = 0;
+ this->path_ = 0;
+ this->query_ = 0;
+}
+
+int
+ACE_HTTP_Addr::set (const ACE_TCHAR *host_name,
+ const ACE_TCHAR *path,
+ const ACE_TCHAR *query,
+ u_short port)
+{
+ if (host_name == 0 || path == 0)
+ return -1;
+
+ this->clear ();
+ ACE_ALLOCATOR_RETURN (this->hostname_, ACE_OS::strdup (host_name), -1);
+ this->port_number_ = port;
+ ACE_ALLOCATOR_RETURN (this->path_, ACE_OS::strdup (path), -1);
+ if (query != 0)
+ ACE_ALLOCATOR_RETURN (this->query_, ACE_OS::strdup (query), -1);
+ else
+ this->query_ = 0;
+
+ size_t size = this->url_size (1);
+
+ ACE_TCHAR *buffer;
+ ACE_ALLOCATOR_RETURN (buffer,
+ reinterpret_cast<ACE_TCHAR *> (ACE_OS::malloc (size)),
+ -1);
+ if (this->addr_to_string (buffer, size, 1) == -1)
+ return -1;
+ this->set_url (buffer);
+ return 0;
+}
+
+int
+ACE_HTTP_Addr::set (const ACE_HTTP_Addr &addr)
+{
+ if (this->ACE_URL_Addr::set (addr) != 0)
+ return -1;
+ this->clear ();
+ if (addr.hostname_ != 0)
+ ACE_ALLOCATOR_RETURN (this->hostname_, ACE_OS::strdup (addr.hostname_), -1);
+ else
+ ACE_ALLOCATOR_RETURN (this->hostname_, ACE_OS::strdup (ACE_TEXT ("")), -1);
+ if (addr.path_ != 0)
+ ACE_ALLOCATOR_RETURN (this->path_, ACE_OS::strdup (addr.path_), -1);
+ else
+ ACE_ALLOCATOR_RETURN (this->path_, ACE_OS::strdup (ACE_TEXT ("")), -1);
+ this->port_number_ = addr.port_number_;
+ if (addr.query_ != 0)
+ ACE_ALLOCATOR_RETURN (this->query_, ACE_OS::strdup (addr.query_), -1);
+ else
+ this->query_ = 0;
+ return 0;
+}
+
+void
+ACE_HTTP_Addr::clear (void)
+{
+ if (this->hostname_ != 0)
+ ACE_OS::free (this->hostname_);
+ if (this->path_ != 0)
+ ACE_OS::free (this->path_);
+ if (this->query_ != 0)
+ ACE_OS::free (this->query_);
+}
+
+size_t
+ACE_HTTP_Addr::url_size (int flags) const
+{
+ // Notice that we cannot hard-code the value because the size in
+ // wchar's may be different.
+ size_t size =
+ + sizeof (ACE_TEXT ("http://"))
+ + sizeof (ACE_TEXT ("/:?")); // separators
+
+ size_t chars =
+ + (this->path_?ACE_OS::strlen (this->path_):0)
+ + (this->query_?ACE_OS::strlen (this->query_):0);
+
+
+ if (flags == 0)
+ {
+ size += sizeof (ACE_TEXT("255.255.255.255"));
+ }
+ else
+ {
+ chars += ACE_OS::strlen (this->hostname_);
+ }
+
+ if (this->port_number_ != ACE_DEFAULT_HTTP_PORT)
+ {
+ size += sizeof (ACE_TEXT(":65335"));
+ }
+
+ size += chars * sizeof(ACE_TCHAR);
+
+ return size;
+}
+
+inline int
+path_copy (const ACE_TCHAR *begin,
+ const ACE_TCHAR * /* end */,
+ ACE_TCHAR *& target,
+ const ACE_TCHAR *src)
+{
+ // Copy one character at a time, if we find a /../ we go back to the
+ // previous '/'
+ for (; *src != 0; ++src)
+ {
+ ACE_TCHAR c = *src;
+ switch (c)
+ {
+ case '/':
+ if (src[1] == '.' && src[2] == '.' && src[3] == '/')
+ {
+ while (target != begin && *(--target) != '/');
+ src += 3;
+ }
+ else if (src[1] == '.' && src[2] == '/')
+ {
+ src += 2;
+ }
+ else
+ {
+ *target = c;
+ ++target;
+ }
+ break;
+ default:
+ *target = c;
+ ++target;
+ }
+ }
+ return 0;
+}
+
+ACE_URL_Addr*
+ACE_HTTP_Addr::create_relative_address (const ACE_TCHAR *url) const
+{
+ if (ACE_URL_Addr::known_scheme (url))
+ return ACE_URL_Addr::create_address (url);
+
+ ACE_HTTP_Addr* addr = 0;
+ if (url[0] == '/')
+ {
+ ACE_NEW_RETURN (addr, ACE_HTTP_Addr (this->get_hostname (),
+ url + 1,
+ 0,
+ this->get_port_number ()),
+ 0);
+ }
+ else
+ {
+ const ACE_TCHAR *path = this->get_path ();
+ ACE_TCHAR *buf;
+ size_t n = ACE_OS::strlen (url)
+ + ACE_OS::strlen (path)
+ + 2;
+ ACE_NEW_RETURN (buf,
+ ACE_TCHAR [n],
+ 0);
+
+ // We copy the contens of <path> into <buf>; but simplifying the
+ // path, to avoid infinite loop like:
+ // "foo/../foo/../foo/../foo/../foo/index.html"
+ //
+ ACE_TCHAR *target = buf;
+
+ // Copy the path
+ path_copy (buf, buf + n, target, path);
+
+ if (url[0] == '#')
+ {
+ // Remove any # from the path
+ ACE_TCHAR *p = target;
+ while (p != buf && *(--p) != '#');
+ if (p != buf)
+ target = p;
+ }
+ else
+ {
+ // Go back to the last / to remove the basename.
+ while (target != buf && *(--target) != '/');
+ // Go back if we begin with '../'
+ while ((url[0] == '.' && url[1] == '.' && url[2] == '/')
+ || (url[0] == '.' && url[1] == '/'))
+ {
+ if (url[1] == '.')
+ {
+ // A ../ go back
+ while (target != buf && *(--target) != '/');
+ url += 3;
+ }
+ else
+ {
+ // A ./ remove
+ url += 2;
+ }
+ }
+
+ *target = '/'; ++target;
+ }
+ // Copy the url
+ path_copy (buf, buf + n, target, url);
+ // null terminate.
+ *target = 0;
+ ACE_NEW_RETURN (addr, ACE_HTTP_Addr (this->get_hostname (),
+ buf,
+ 0,
+ this->get_port_number ()),
+ 0);
+ delete[] buf;
+ }
+ return addr;
+}
+
+int
+ACE_HTTP_Addr::string_to_addr (const ACE_TCHAR *address)
+{
+ if (address == 0)
+ return -1;
+
+ if (ACE_OS::strncasecmp (http, address, http_size) != 0)
+ return -1;
+
+ this->clear ();
+ this->hostname_ = 0;
+ this->path_ = 0;
+ this->query_ = 0;
+
+ // Save the original URL....
+ if (this->ACE_URL_Addr::string_to_addr (address) != 0)
+ return -1;
+
+ const ACE_TCHAR *string = address;
+ string += http_size;
+ string += 2; // == strlen ("//");
+
+ // Make a copy of the string to manipulate it.
+ ACE_ALLOCATOR_RETURN (this->hostname_, ACE_OS::strdup (string), -1);
+
+ ACE_TCHAR *path_start = ACE_OS::strchr (this->hostname_, '/');
+ if (path_start != 0)
+ {
+ // terminate the host:port substring
+ path_start[0] = '\0';
+ path_start++;
+ ACE_TCHAR *query_start = ACE_OS::strchr (path_start, '?');
+ if (query_start != 0)
+ {
+ query_start[0] = '\0';
+ query_start++;
+ ACE_ALLOCATOR_RETURN (this->query_,
+ ACE_OS::strdup (query_start),
+ -1);
+ }
+ ACE_ALLOCATOR_RETURN (this->path_, ACE_OS::strdup (path_start), -1);
+ }
+
+ // By now t is null terminated at the start of the path, find the
+ // port (if present).
+ ACE_TCHAR *port_start = ACE_OS::strchr(this->hostname_, ':');
+ this->port_number_ = ACE_DEFAULT_HTTP_PORT;
+ if (port_start != 0)
+ {
+ // terminate the ipaddr.
+ port_start[0] = '\0';
+ port_start++;
+ this->port_number_ = ACE_OS::atoi (port_start);
+ }
+
+ return 0;
+}
+
+int
+ACE_HTTP_Addr::addr_to_string (ACE_TCHAR *buffer,
+ size_t size,
+ int flags) const
+{
+ if (size < this->url_size (flags))
+ return -1;
+
+ if (this->hostname_ == 0)
+ return -1;
+
+ size_t n = ACE_OS::sprintf (buffer,
+ ACE_TEXT ("http://"));
+ if (flags == 0)
+ {
+ ACE_INET_Addr inet = this->get_inet_address ();
+ n += ACE_OS::sprintf (buffer + n, ACE_PRINTF_S, inet.get_host_addr ());
+ }
+ else
+ {
+ n += ACE_OS::sprintf (buffer + n, ACE_PRINTF_S, this->hostname_);
+ }
+
+ if (this->port_number_ != ACE_DEFAULT_HTTP_PORT)
+ {
+ n += ACE_OS::sprintf (buffer + n, ACE_TEXT (":%d"), this->port_number_);
+ }
+ if (this->path_ != 0)
+ {
+ n += ACE_OS::sprintf (buffer + n,
+ ACE_TEXT ("/") ACE_PRINTF_S,
+ this->path_);
+ }
+ if (this->query_ != 0)
+ {
+ n += ACE_OS::sprintf (buffer + n,
+ ACE_TEXT ("?") ACE_PRINTF_S,
+ this->query_);
+ }
+ return 0;
+}
+
+int
+ACE_HTTP_Addr::accept (ACE_URL_Addr_Visitor *visitor)
+{
+ return visitor->visit (this);
+}
+
+// ****************************************************************
+
+ACE_FTP_Addr::ACE_FTP_Addr (void)
+ : user_ (0),
+ password_ (0),
+ hostname_ (0),
+ path_ (0)
+{
+}
+
+ACE_FTP_Addr::ACE_FTP_Addr (const ACE_TCHAR *host_name,
+ const ACE_TCHAR *path,
+ const ACE_TCHAR *user,
+ const ACE_TCHAR *password)
+ : user_ (0),
+ password_ (0),
+ hostname_ (0),
+ path_ (0)
+{
+ this->set (host_name, path, user, password);
+}
+
+ACE_FTP_Addr::ACE_FTP_Addr (const ACE_FTP_Addr& addr)
+ : ACE_URL_Addr (),
+ user_ (0),
+ password_ (0),
+ hostname_ (0),
+ path_ (0)
+{
+ this->set (addr);
+}
+
+ACE_FTP_Addr::~ACE_FTP_Addr (void)
+{
+ this->clear ();
+}
+
+int
+ACE_FTP_Addr::set (const ACE_TCHAR *host_name,
+ const ACE_TCHAR *path,
+ const ACE_TCHAR *user,
+ const ACE_TCHAR *password)
+{
+ if (host_name == 0 || path == 0)
+ return -1;
+ this->clear ();
+ ACE_ALLOCATOR_RETURN (this->hostname_, ACE_OS::strdup (host_name), -1);
+ ACE_ALLOCATOR_RETURN (this->path_, ACE_OS::strdup (path), -1);
+ if (user != 0)
+ ACE_ALLOCATOR_RETURN (this->user_, ACE_OS::strdup (user), -1);
+ else
+ this->user_ = 0;
+ if (this->password_ != 0)
+ ACE_ALLOCATOR_RETURN (this->password_, ACE_OS::strdup (password), -1);
+ else
+ this->password_ = 0;
+
+ size_t size = this->url_size (1);
+
+ ACE_TCHAR *buffer;
+ ACE_ALLOCATOR_RETURN (buffer,
+ reinterpret_cast<ACE_TCHAR *> (ACE_OS::malloc (size)),
+ -1);
+ if (this->addr_to_string (buffer, size, 1) == -1)
+ return -1;
+ this->set_url (buffer);
+ return 0;
+}
+
+int
+ACE_FTP_Addr::set (const ACE_FTP_Addr& addr)
+{
+ if (this->ACE_URL_Addr::set (addr) != 0)
+ return -1;
+ this->clear ();
+ ACE_ALLOCATOR_RETURN (this->hostname_, ACE_OS::strdup (addr.hostname_), -1);
+ ACE_ALLOCATOR_RETURN (this->path_, ACE_OS::strdup (addr.path_), -1);
+ if (addr.user_ != 0)
+ ACE_ALLOCATOR_RETURN (this->user_, ACE_OS::strdup (addr.user_), -1);
+ else
+ this->user_ = 0;
+ if (addr.password_ != 0)
+ ACE_ALLOCATOR_RETURN (this->password_, ACE_OS::strdup (addr.password_), -1);
+ else
+ this->password_ = 0;
+ return 0;
+}
+
+void
+ACE_FTP_Addr::clear (void)
+{
+ if (this->hostname_ != 0)
+ ACE_OS::free (this->hostname_);
+ if (this->path_ != 0)
+ ACE_OS::free (this->path_);
+ if (this->user_ != 0)
+ ACE_OS::free (this->user_);
+ if (this->password_ != 0)
+ ACE_OS::free (this->password_);
+}
+
+size_t
+ACE_FTP_Addr::url_size (int flags) const
+{
+ // Notice that we cannot hard-code the value because the size in
+ // wchar's may be different.
+ size_t size =
+ + sizeof (ACE_TEXT ("ftp://"))
+ + sizeof (ACE_TEXT ("@:/")); // separators
+
+ size_t chars =
+ + (this->user_?ACE_OS::strlen (this->path_):0)
+ + (this->password_?ACE_OS::strlen (this->password_):0)
+ + (this->path_?ACE_OS::strlen (this->path_):0);
+
+ if (flags == 0)
+ {
+ size += sizeof (ACE_TEXT("255.255.255.255"));
+ }
+ else
+ {
+ chars += ACE_OS::strlen (this->hostname_);
+ }
+
+ size += chars * sizeof(ACE_TCHAR);
+ return size;
+}
+
+int
+ACE_FTP_Addr::addr_to_string (ACE_TCHAR *buffer,
+ size_t size,
+ int flags) const
+{
+ if (size < this->url_size (flags))
+ return -1;
+
+ size_t n = ACE_OS::sprintf (buffer,
+ ACE_TEXT ("ftp://"));
+
+ if (this->user_ != 0)
+ {
+ n += ACE_OS::sprintf (buffer + n, ACE_PRINTF_S, this->user_);
+ }
+ if (this->password_ != 0)
+ {
+ n += ACE_OS::sprintf (buffer + n,
+ ACE_TEXT (":") ACE_PRINTF_S,
+ this->password_);
+ }
+
+ if (this->user_ != 0)
+ {
+ n += ACE_OS::sprintf (buffer + n, ACE_TEXT ("@"));
+ }
+
+ if (flags == 0)
+ {
+ ACE_INET_Addr inet = this->get_inet_address ();
+ n += ACE_OS::sprintf (buffer + n, ACE_PRINTF_S, inet.get_host_addr ());
+ }
+ else
+ {
+ n += ACE_OS::sprintf (buffer + n, ACE_PRINTF_S, this->hostname_);
+ }
+ if (this->path_ != 0)
+ {
+ n += ACE_OS::sprintf (buffer + n,
+ ACE_TEXT ("/") ACE_PRINTF_S,
+ this->path_);
+ }
+ return 0;
+}
+
+int
+ACE_FTP_Addr::string_to_addr (const ACE_TCHAR *address)
+{
+ if (address == 0)
+ return -1;
+ if (ACE_OS::strncasecmp (ftp, address, ftp_size) != 0)
+ return -1;
+
+ this->clear ();
+ this->hostname_ = 0;
+ this->user_ = 0;
+ this->password_ = 0;
+ this->path_ = 0;
+
+ // Save the original URL....
+ this->ACE_URL_Addr::string_to_addr (address);
+
+ const ACE_TCHAR *string = address;
+ string += ftp_size;
+ string += 2; // == strlen ("//");
+
+ // Make a copy of the string to manipulate it.
+ ACE_TCHAR *t;
+ ACE_ALLOCATOR_RETURN (t, ACE_OS::strdup (string), -1);
+
+ ACE_TCHAR *path_start = ACE_OS::strchr (t, '/');
+ if (path_start != 0)
+ {
+ // terminate the host:port substring
+ path_start[0] = '\0';
+ path_start++;
+ ACE_ALLOCATOR_RETURN (this->path_, ACE_OS::strdup (path_start), -1);
+ }
+
+ ACE_TCHAR *host_start = ACE_OS::strchr (t, '@');
+ if (host_start != 0)
+ {
+ host_start[0] = '\0';
+ host_start++;
+ ACE_ALLOCATOR_RETURN (this->hostname_,
+ ACE_OS::strdup (host_start),
+ -1);
+ ACE_TCHAR *pass_start = ACE_OS::strchr (t, ':');
+ if (pass_start != 0)
+ {
+ pass_start[0] = '\0';
+ pass_start++;
+ ACE_ALLOCATOR_RETURN (this->password_,
+ ACE_OS::strdup (pass_start),
+ -1);
+ }
+ this->user_ = t;
+ }
+ else
+ {
+ this->hostname_ = t;
+ }
+
+ return 0;
+}
+
+int
+ACE_FTP_Addr::accept (ACE_URL_Addr_Visitor* visitor)
+{
+ return visitor->visit (this);
+}
+
+// ****************************************************************
+
+ACE_Mailto_Addr::ACE_Mailto_Addr (void)
+ : user_ (0),
+ hostname_ (0),
+ headers_ (0)
+{
+}
+
+ACE_Mailto_Addr::ACE_Mailto_Addr (const ACE_TCHAR *user,
+ const ACE_TCHAR *hostname,
+ const ACE_TCHAR *headers)
+ : user_ (0),
+ hostname_ (0),
+ headers_ (0)
+{
+ this->set (user, hostname, headers);
+}
+
+ACE_Mailto_Addr::ACE_Mailto_Addr (const ACE_Mailto_Addr &addr)
+ : ACE_URL_Addr (addr),
+ user_ (0),
+ hostname_ (0),
+ headers_ (0)
+{
+ this->set (addr);
+}
+
+ACE_Mailto_Addr::~ACE_Mailto_Addr (void)
+{
+ this->clear ();
+}
+
+int
+ACE_Mailto_Addr::set (const ACE_TCHAR *user,
+ const ACE_TCHAR *hostname,
+ const ACE_TCHAR *headers)
+{
+ if (user == 0 || hostname == 0)
+ return -1;
+ this->clear ();
+ ACE_ALLOCATOR_RETURN (this->user_, ACE_OS::strdup (user), -1);
+ ACE_ALLOCATOR_RETURN (this->hostname_, ACE_OS::strdup (hostname), -1);
+ if (headers != 0)
+ ACE_ALLOCATOR_RETURN (this->headers_, ACE_OS::strdup (headers), -1);
+ else
+ this->headers_ = 0;
+ size_t size = this->url_size (1);
+ ACE_TCHAR *buffer;
+ ACE_ALLOCATOR_RETURN (buffer,
+ reinterpret_cast<ACE_TCHAR *> (ACE_OS::malloc (size)),
+ -1);
+ if (this->addr_to_string (buffer, size, 1) == -1)
+ return -1;
+ this->set_url (buffer);
+ return 0;
+}
+
+int
+ACE_Mailto_Addr::set (const ACE_Mailto_Addr &addr)
+{
+ if (this->ACE_URL_Addr::set (addr) != 0)
+ return -1;
+ this->clear ();
+ ACE_ALLOCATOR_RETURN (this->user_, ACE_OS::strdup (addr.user_), -1);
+ ACE_ALLOCATOR_RETURN (this->hostname_, ACE_OS::strdup (addr.hostname_), -1);
+ if (addr.headers_ != 0)
+ ACE_ALLOCATOR_RETURN (this->headers_, ACE_OS::strdup (addr.headers_), -1);
+ else
+ this->headers_ = 0;
+ return 0;
+}
+
+void
+ACE_Mailto_Addr::clear (void)
+{
+ if (this->user_ != 0)
+ ACE_OS::free (this->user_);
+ if (this->hostname_ != 0)
+ ACE_OS::free (this->hostname_);
+ if (this->headers_ != 0)
+ ACE_OS::free (this->headers_);
+}
+
+size_t
+ACE_Mailto_Addr::url_size (int) const
+{
+ // Notice that we cannot hard-code the value because the size in
+ // wchar's may be different.
+ size_t size = sizeof (ACE_TEXT ("mailto:"))
+ + sizeof (ACE_TEXT ("@?")); // separators
+
+ size_t chars =
+ + (this->user_?ACE_OS::strlen (this->user_):0)
+ + (this->hostname_?ACE_OS::strlen (this->hostname_):0)
+ + (this->headers_?ACE_OS::strlen (this->headers_):0);
+ size += chars * sizeof (ACE_TCHAR);
+
+ return size;
+}
+
+int
+ACE_Mailto_Addr::addr_to_string (ACE_TCHAR *buffer,
+ size_t size,
+ int flags) const
+{
+ if (size < this->url_size (flags))
+ return -1;
+ if (this->user_ == 0 || this->hostname_ == 0)
+ return -1;
+
+ size_t n = ACE_OS::sprintf (buffer,
+ ACE_TEXT ("mailto:") ACE_PRINTF_S ACE_TEXT
+ ("@") ACE_PRINTF_S,
+ this->user_, this->hostname_);
+ if (this->headers_ != 0)
+ {
+ n += ACE_OS::sprintf (buffer + n, ACE_TEXT ("?") ACE_PRINTF_S,
+ this->headers_);
+ }
+
+ return 0;
+}
+
+int
+ACE_Mailto_Addr::string_to_addr (const ACE_TCHAR *address)
+{
+ if (ACE_OS::strncasecmp (mailto, address, mailto_size) != 0)
+ return -1;
+
+ this->clear ();
+ this->user_ = 0;
+ this->hostname_ = 0;
+ this->headers_ = 0;
+
+ // Save the original URL....
+ if (this->ACE_URL_Addr::string_to_addr (address) != 0)
+ return -1;
+
+ const ACE_TCHAR *string = address;
+ string += mailto_size;
+
+ // Make a copy of the string to manipulate it.
+ ACE_TCHAR *t;
+ ACE_ALLOCATOR_RETURN (t, ACE_OS::strdup (string), -1);
+
+ ACE_TCHAR *host_start = ACE_OS::strchr (t, '@');
+ if (host_start != 0)
+ {
+ // terminate the host:port substring
+ host_start[0] = '\0';
+ host_start++;
+ ACE_TCHAR *headers_start = ACE_OS::strchr (host_start, '?');
+ if (headers_start != 0)
+ {
+ headers_start[0] = '\0';
+ headers_start++;
+ ACE_ALLOCATOR_RETURN (this->headers_,
+ ACE_OS::strdup (headers_start),
+ -1);
+ }
+ ACE_ALLOCATOR_RETURN (this->hostname_, ACE_OS::strdup (host_start), -1);
+ }
+ else
+ {
+ ACE_OS::free (t);
+ return -1;
+ }
+ this->user_ = t;
+
+ return 0;
+}
+
+int
+ACE_Mailto_Addr::accept (ACE_URL_Addr_Visitor* visitor)
+{
+ return visitor->visit (this);
+}
diff --git a/ACE/websvcs/lib/URL_Addr.h b/ACE/websvcs/lib/URL_Addr.h
new file mode 100644
index 00000000000..1e016260989
--- /dev/null
+++ b/ACE/websvcs/lib/URL_Addr.h
@@ -0,0 +1,404 @@
+/* -*- C++ -*- */
+// $Id$
+
+// ============================================================================
+//
+// = LIBRARY
+// ace
+//
+// = FILENAME
+// URL_Addr.h
+//
+// = AUTHOR
+// Douglas C. Schmidt <schmidt@cs.wustl.edu>
+//
+// ============================================================================
+
+#ifndef ACE_URL_ADDR_H
+#define ACE_URL_ADDR_H
+
+#include "ace/INET_Addr.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+#include "websvcs_export.h"
+#include "ace/ACE.h"
+
+class ACE_URL_Addr_Visitor;
+
+class ACE_WEBSVCS_Export ACE_URL_Addr : public ACE_Addr
+{
+ // = TITLE
+ // Defines the interface for an URL
+ //
+ // = DESCRIPTION
+ // All URLs derive from this class
+ //
+public:
+ ACE_URL_Addr (void);
+ // Constructor.
+
+ ACE_URL_Addr (const ACE_URL_Addr& address);
+ // The copy constructor.
+
+ ACE_URL_Addr& operator= (const ACE_URL_Addr& address);
+ // The assignment operator
+
+ virtual ~ACE_URL_Addr (void);
+ // destructor
+
+ const ACE_TCHAR *get_url (void) const;
+ // Get the original URL
+
+ int set (const ACE_URL_Addr& address);
+ // Essentially the copy contructor.
+
+ virtual int string_to_addr (const ACE_TCHAR *address);
+ // Initializes from the scheme specific address, for instance: if
+ // the address is an http URL it will initialize the address from
+ // an string such as "www.cs.wustl.edu/~schmidt"
+
+ virtual int addr_to_string (ACE_TCHAR *s,
+ size_t size,
+ int flags = 0) const;
+ // Write the address in the scheme specific representation.
+ // <flags> provides control over scheme specific features (such as
+ // using numeric vs. fully qualified host names).
+
+ virtual int accept (ACE_URL_Addr_Visitor* visitor);
+ // The accept method in the Visitor Pattern. Should return 0 on
+ // success and not 0 on failure.
+
+ static ACE_URL_Addr* create_address (const ACE_TCHAR *url);
+ // Create an address from a complete URL, such as "http://www/foo"
+ // or "ftp://ftp.here/get_this".
+
+ static int known_scheme (const ACE_TCHAR *url);
+ // Returns 1 if the URL scheme is recognized, 0 otherwise.
+
+ u_long hash (void) const;
+ // Hash function
+
+protected:
+ void set_url (ACE_TCHAR *url);
+ // Allows the derived classes to store the compact representation of
+ // the URL
+
+private:
+ ACE_TCHAR *url_;
+};
+
+class ACE_HTTP_Addr;
+class ACE_FTP_Addr;
+class ACE_Mailto_Addr;
+// @@ TODO add more URL schemes as needed.
+// class ACE_File_Addr;
+// class ACE_AFS_Addr;
+// class ACE_News_Addr;
+// class ACE_NNTP_Addr;
+// class ACE_CID_Addr;
+// class ACE_MID_Addr;
+// class ACE_WAIS_Addr;
+// class ACE_Prospero_Addr;
+// class ACE_Telnet_Addr;
+// class ACE_Rlogin_Addr;
+// class ACE_TN3270_Addr;
+// class ACE_Gopher_Addr;
+
+class ACE_WEBSVCS_Export ACE_URL_Addr_Visitor
+{
+ // = TITLE
+ // Implements a Visitor object for the ACE_URL hierarchy.
+ //
+ // = DESCRIPTION
+ // The manipulation of URL objects is much simpler if we use the
+ // Visitor pattern to solve the double dispatch problem between
+ // the "what to do on a URL" vs. "what to do on each kind of
+ // URL".
+ //
+public:
+ virtual ~ACE_URL_Addr_Visitor (void);
+ // Destructor
+
+ virtual int visit (ACE_URL_Addr*);
+ virtual int visit (ACE_HTTP_Addr*);
+ virtual int visit (ACE_FTP_Addr*);
+ virtual int visit (ACE_Mailto_Addr*);
+ // The visit methods for all the hierarchy.
+ // The default implementation is a nop (instead of a pure virtual
+ // function) to facilitate the addition of new members in the
+ // hierarchy.
+ // virtual int visit (ACE_AFS_Addr*);
+ // virtual int visit (ACE_News_Addr*);
+ // virtual int visit (ACE_NNTP_Addr*);
+};
+
+// ****************************************************************
+
+class ACE_WEBSVCS_Export ACE_HTTP_Addr : public ACE_URL_Addr
+{
+ // = TITLE
+ // Defines the HTTP scheme addresses
+ //
+ // = DESCRIPTION
+ // Encapsulates an HTTP URL; the most general form is:
+ //
+ // http://host:port/path?query
+ //
+ // but these are also accepted:
+ //
+ // http://host/path?query
+ // http://host:port/path
+ // http://host/path
+ //
+public:
+ ACE_HTTP_Addr (void);
+ // Constructor
+
+ ACE_HTTP_Addr (const ACE_TCHAR *host_name,
+ const ACE_TCHAR *path,
+ const ACE_TCHAR *query = 0,
+ u_short port = ACE_DEFAULT_HTTP_PORT);
+ // Construct an HTTP URL from the host, path, query and port.
+
+ int set (const ACE_TCHAR *host_name,
+ const ACE_TCHAR *path,
+ const ACE_TCHAR *query = 0,
+ u_short port = ACE_DEFAULT_HTTP_PORT);
+ // Essentially the constructor above.
+
+ ACE_HTTP_Addr (const ACE_HTTP_Addr &addr);
+ // Copy constructor.
+
+ ACE_HTTP_Addr& operator= (const ACE_HTTP_Addr &addr);
+ // Assignment operator.
+
+ int set (const ACE_HTTP_Addr &addr);
+ // Essentially the copy constructor.
+
+ virtual ~ACE_HTTP_Addr (void);
+ // Destructor
+
+ ACE_INET_Addr get_inet_address (void) const;
+ // Build the INET_Address implicit in the URL, notice that we
+ // maintain the hostname in its string representation, because the
+ // URL can be can be refering to an hostname that cannot be
+ // validated at this point.
+
+ const ACE_TCHAR *get_hostname (void) const;
+ // Get the name of the host.
+
+ u_short get_port_number (void) const;
+ // Get the port number.
+
+ const ACE_TCHAR *get_path (void) const;
+ // Get the path component in the URL
+
+ const ACE_TCHAR *get_query (void) const;
+ // Get the query component in the URL
+
+ ACE_URL_Addr* create_relative_address (const ACE_TCHAR *url) const;
+ // Create an address from a (possibly) relative URL, such as
+ // "../foo.html", or "/icons/bar.gif"
+ // If the URL is absolute (like "http://www/foo" or "ftp:host/bar")
+ // it simply returns the correct ACE_URL_Addr object; but if the URL
+ // is not absolute then it is interpreted as relative from the
+ // current address. In that case url is just a path, if it is a
+ // relative path the new address simply concatenates the path and
+ // uses the same host:port; if it is an absolute path only the host
+ // and port are used.
+
+ // = The ACE_URL methods, see the documentation above.
+ virtual int string_to_addr (const ACE_TCHAR *address);
+ virtual int addr_to_string (ACE_TCHAR *s,
+ size_t size,
+ int flags = 0) const;
+ virtual int accept (ACE_URL_Addr_Visitor* visitor);
+
+private:
+ size_t url_size (int flags = 0) const;
+ // Compute the size required to store the URL in a string
+ // representation.
+
+ void clear (void);
+ // Helper method to cleanup resources
+
+private:
+ ACE_TCHAR *hostname_;
+ u_short port_number_;
+ // The host:port component in the URL
+
+ ACE_TCHAR *path_;
+ // The path component in the URL
+
+ ACE_TCHAR *query_;
+ // The query component in the URL
+};
+
+// ****************************************************************
+
+class ACE_WEBSVCS_Export ACE_FTP_Addr : public ACE_URL_Addr
+{
+ // = TITLE
+ // Defines the FTP scheme addresses
+ //
+ // = DESCRIPTION
+ // Encapsulates an FTP URL; usually an FTP URL is of the form:
+ //
+ // ftp://hostname/path
+ //
+ // but the most general form is:
+ //
+ // ftp://user:password@hostname/path
+ //
+ // the [:password] part can be omitted too.
+ //
+public:
+ ACE_FTP_Addr (void);
+ // Constructor
+
+ ACE_FTP_Addr (const ACE_TCHAR *host_name,
+ const ACE_TCHAR *path,
+ const ACE_TCHAR *user = 0,
+ const ACE_TCHAR *password = 0);
+ // Construct an FTP URL from the host_name, the path, the username
+ // and the password.
+
+ int set (const ACE_TCHAR *host_name,
+ const ACE_TCHAR *path,
+ const ACE_TCHAR *user = 0,
+ const ACE_TCHAR *password = 0);
+ // Essentially the constructor above.
+
+ ACE_FTP_Addr (const ACE_FTP_Addr &addr);
+ // Copy constructor.
+
+ ACE_FTP_Addr& operator= (const ACE_FTP_Addr &addr);
+ // Assignment operator
+
+ int set (const ACE_FTP_Addr &addr);
+ // Essentially the copy constructor.
+
+ virtual ~ACE_FTP_Addr (void);
+ // Destructor
+
+ const ACE_TCHAR *get_hostname (void) const;
+ // Get the host name component in the URL
+
+ const ACE_TCHAR *get_user (void) const;
+ // Get the username component in the URL
+
+ const ACE_TCHAR *get_passwd (void) const;
+ // Get the password component in the URL
+
+ const ACE_TCHAR *get_path (void) const;
+ // Get the path component in the URL
+
+ ACE_INET_Addr get_inet_address (void) const;
+ // Obtain the INET_Address implicit in the URL, can be used to
+ // obtain the host and the port.
+
+ // = The ACE_Addr methods, see the documentation above.
+ virtual int string_to_addr (const ACE_TCHAR *address);
+ virtual int addr_to_string (ACE_TCHAR *s,
+ size_t size,
+ int flags = 0) const;
+ virtual int accept (ACE_URL_Addr_Visitor* visitor);
+
+private:
+ size_t url_size (int flags = 0) const;
+ // Compute the size required to store the URL in a string
+ // representation.
+
+ void clear (void);
+ // Helper method to release the internal resources
+
+private:
+ ACE_TCHAR *user_;
+ ACE_TCHAR *password_;
+ // The login name
+
+ ACE_TCHAR *hostname_;
+ // The hostname part.
+
+ ACE_TCHAR *path_;
+ // The other components.
+};
+
+// ****************************************************************
+
+class ACE_WEBSVCS_Export ACE_Mailto_Addr : public ACE_URL_Addr
+{
+ // = TITLE
+ // Defines the mailto scheme addresses
+ //
+ // = DESCRIPTION
+ // Encapsulates an URL that refers to an email address.
+ //
+public:
+ ACE_Mailto_Addr (void);
+ // Constructor
+
+ ACE_Mailto_Addr (const ACE_TCHAR *user,
+ const ACE_TCHAR *hostname,
+ const ACE_TCHAR *headers = 0);
+ // Construct an FTP URL from the host, path and headers.
+
+ int set (const ACE_TCHAR *user,
+ const ACE_TCHAR *hostname,
+ const ACE_TCHAR *headers = 0);
+ // Essentially the constructor above.
+
+ ACE_Mailto_Addr (const ACE_Mailto_Addr &addr);
+ // Copy constructor.
+
+ ACE_Mailto_Addr& operator= (const ACE_Mailto_Addr &addr);
+ // Assignment operator
+
+ int set (const ACE_Mailto_Addr &addr);
+ // Essentially the copy constructor.
+
+ virtual ~ACE_Mailto_Addr (void);
+ // Destructor
+
+ const ACE_TCHAR *get_user (void) const;
+ // Get the username component in the URL
+
+ const ACE_TCHAR *get_hostname (void) const;
+ // Get the hostname component in the URL
+
+ const ACE_TCHAR *get_headers (void) const;
+ // Get the headers as a single string
+
+ // @@ TODO A mailto: URL can contain multiple headers, an iterator
+ // over them would be a good idea. Similarly a method to *add*
+ // headers would be nice also.
+
+ // = The ACE_URL methods, see the documentation above.
+ virtual int string_to_addr (const ACE_TCHAR *address);
+ virtual int addr_to_string (ACE_TCHAR *s,
+ size_t size,
+ int flags = 0) const;
+ virtual int accept (ACE_URL_Addr_Visitor* visitor);
+
+private:
+ size_t url_size (int flags = 0) const;
+ // Compute the size required to store the URL in a string
+ // representation.
+
+ void clear (void);
+ // Helper method to cleanup resources
+
+private:
+ ACE_TCHAR *user_;
+ ACE_TCHAR *hostname_;
+ ACE_TCHAR *headers_;
+};
+
+#if defined (__ACE_INLINE__)
+#include "URL_Addr.i"
+#endif /* __ACE_INLINE__ */
+
+#endif /* ACE_URL_ADDR_H */
diff --git a/ACE/websvcs/lib/URL_Addr.i b/ACE/websvcs/lib/URL_Addr.i
new file mode 100644
index 00000000000..2e3c8ddba89
--- /dev/null
+++ b/ACE/websvcs/lib/URL_Addr.i
@@ -0,0 +1,155 @@
+// -*- C++ -*-
+// $Id$
+
+// ****************************************************************
+
+#include "ace/OS_NS_string.h"
+
+ACE_INLINE
+ACE_URL_Addr::ACE_URL_Addr (const ACE_URL_Addr& address)
+ : ACE_Addr (),
+ url_ (address.url_ == 0 ? 0 : ACE_OS::strdup (address.url_))
+{
+}
+
+ACE_INLINE ACE_URL_Addr&
+ACE_URL_Addr::operator= (const ACE_URL_Addr& address)
+{
+ if (this == &address)
+ return *this;
+
+ this->set (address);
+ return *this;
+}
+
+ACE_INLINE const ACE_TCHAR *
+ACE_URL_Addr::get_url (void) const
+{
+ return this->url_;
+}
+
+ACE_INLINE void
+ACE_URL_Addr::set_url (ACE_TCHAR *url)
+{
+ this->url_ = url;
+}
+
+ACE_INLINE u_long
+ACE_URL_Addr::hash (void) const
+{
+ return ACE::hash_pjw (this->url_);
+}
+
+// ****************************************************************
+
+ACE_INLINE ACE_HTTP_Addr&
+ACE_HTTP_Addr::operator= (const ACE_HTTP_Addr& rhs)
+{
+ if (this == &rhs)
+ return *this;
+
+ this->set (rhs);
+ return *this;
+}
+
+ACE_INLINE ACE_INET_Addr
+ACE_HTTP_Addr::get_inet_address (void) const
+{
+ return ACE_INET_Addr (this->port_number_, this->hostname_);
+}
+
+ACE_INLINE const ACE_TCHAR *
+ACE_HTTP_Addr::get_hostname (void) const
+{
+ return this->hostname_;
+}
+
+ACE_INLINE u_short
+ACE_HTTP_Addr::get_port_number (void) const
+{
+ return this->port_number_;
+}
+
+ACE_INLINE const ACE_TCHAR *
+ACE_HTTP_Addr::get_path (void) const
+{
+ return this->path_;
+}
+
+ACE_INLINE const ACE_TCHAR *
+ACE_HTTP_Addr::get_query (void) const
+{
+ return this->query_;
+}
+
+// ****************************************************************
+
+ACE_INLINE ACE_FTP_Addr&
+ACE_FTP_Addr::operator= (const ACE_FTP_Addr& rhs)
+{
+ if (this == &rhs)
+ return *this;
+
+ this->set (rhs);
+ return *this;
+}
+
+ACE_INLINE const ACE_TCHAR *
+ACE_FTP_Addr::get_user (void) const
+{
+ return this->user_;
+}
+
+ACE_INLINE const ACE_TCHAR *
+ACE_FTP_Addr::get_hostname (void) const
+{
+ return this->hostname_;
+}
+
+ACE_INLINE const ACE_TCHAR *
+ACE_FTP_Addr::get_passwd (void) const
+{
+ return this->password_;
+}
+
+ACE_INLINE const ACE_TCHAR *
+ACE_FTP_Addr::get_path (void) const
+{
+ return this->path_;
+}
+
+ACE_INLINE ACE_INET_Addr
+ACE_FTP_Addr::get_inet_address (void) const
+{
+ return ACE_INET_Addr (ACE_TEXT ("ftp"), this->hostname_);
+}
+
+// ****************************************************************
+
+ACE_INLINE ACE_Mailto_Addr&
+ACE_Mailto_Addr::operator= (const ACE_Mailto_Addr& rhs)
+{
+ if (this == &rhs)
+ return *this;
+
+ this->set (rhs);
+ return *this;
+}
+
+ACE_INLINE const ACE_TCHAR *
+ACE_Mailto_Addr::get_user (void) const
+{
+ return this->user_;
+}
+
+ACE_INLINE const ACE_TCHAR *
+ACE_Mailto_Addr::get_hostname (void) const
+{
+ return this->hostname_;
+}
+
+ACE_INLINE const ACE_TCHAR *
+ACE_Mailto_Addr::get_headers (void) const
+{
+ return this->headers_;
+}
diff --git a/ACE/websvcs/lib/lib.mpc b/ACE/websvcs/lib/lib.mpc
new file mode 100644
index 00000000000..339964f65ad
--- /dev/null
+++ b/ACE/websvcs/lib/lib.mpc
@@ -0,0 +1,11 @@
+// -*- MPC -*-
+// $Id$
+
+project(websvcs): acelib {
+ sharedname = websvcs
+ dynamicflags += ACE_WEBSVCS_BUILD_DLL
+ Source_Files {
+ URL_Addr.cpp
+ }
+
+}
diff --git a/ACE/websvcs/lib/websvcs_export.h b/ACE/websvcs/lib/websvcs_export.h
new file mode 100644
index 00000000000..5fe3d7652d5
--- /dev/null
+++ b/ACE/websvcs/lib/websvcs_export.h
@@ -0,0 +1,44 @@
+// -*- C++ -*-
+// $Id$
+// Definition for Win32 Export directives.
+// This file is generated automatically by
+// generate_export_file.pl
+// ------------------------------
+#if !defined (ACE_WEBSVCS_EXPORT_H)
+#define ACE_WEBSVCS_EXPORT_H
+
+#include "ace/config-all.h"
+
+#if defined (ACE_AS_STATIC_LIBS) && !defined (ACE_WEBSVCS_HAS_DLL)
+# define ACE_WEBSVCS_HAS_DLL 0
+#endif /* ACE_AS_STATIC_LIBS && ACE_WEBSVCS_HAS_DLL */
+
+#if !defined (ACE_WEBSVCS_HAS_DLL)
+#define ACE_WEBSVCS_HAS_DLL 1
+#endif /* ! ACE_WEBSVCS_HAS_DLL */
+
+#if defined (ACE_WEBSVCS_HAS_DLL)
+# if (ACE_WEBSVCS_HAS_DLL == 1)
+# if defined (ACE_WEBSVCS_BUILD_DLL)
+# define ACE_WEBSVCS_Export ACE_Proper_Export_Flag
+# define ACE_WEBSVCS_SINGLETON_DECLARATION(T) ACE_EXPORT_SINGLETON_DECLARATION (T)
+# define ACE_WEBSVCS_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) ACE_EXPORT_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK)
+# else
+# define ACE_WEBSVCS_Export ACE_Proper_Import_Flag
+# define ACE_WEBSVCS_SINGLETON_DECLARATION(T) ACE_IMPORT_SINGLETON_DECLARATION (T)
+# define ACE_WEBSVCS_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) ACE_IMPORT_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK)
+# endif /* ACE_WEBSVCS_BUILD_DLL */
+# else
+# define ACE_WEBSVCS_Export
+# define ACE_WEBSVCS_SINGLETON_DECLARATION(T)
+# define ACE_WEBSVCS_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK)
+# endif /* ! ACE_WEBSVCS_HAS_DLL == 1 */
+#else
+# define ACE_WEBSVCS_Export
+# define ACE_WEBSVCS_SINGLETON_DECLARATION(T)
+# define ACE_WEBSVCS_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK)
+#endif /* ACE_WEBSVCS_HAS_DLL */
+
+#endif /* ACE_WEBSVCS_EXPORT_H */
+
+// End of auto generated file.
diff --git a/ACE/websvcs/tests/Makefile.am b/ACE/websvcs/tests/Makefile.am
new file mode 100644
index 00000000000..868befa72a0
--- /dev/null
+++ b/ACE/websvcs/tests/Makefile.am
@@ -0,0 +1,34 @@
+## Process this file with automake to create Makefile.in
+##
+## $Id$
+##
+## This file was generated by MPC. Any changes made directly to
+## this file will be lost the next time it is generated.
+##
+## MPC Command:
+## /acebuilds/ACE_wrappers-repository/bin/mwc.pl -include /acebuilds/MPC/config -include /acebuilds/MPC/templates -feature_file /acebuilds/ACE_wrappers-repository/local.features -noreldefs -type automake -exclude build,Kokyu
+
+ACE_BUILDDIR = $(top_builddir)
+ACE_ROOT = $(top_srcdir)
+
+## Makefile.Websvcs_Test.am
+noinst_PROGRAMS = Test_Url_Addr
+
+Test_Url_Addr_CPPFLAGS = \
+ -I$(ACE_ROOT) \
+ -I$(ACE_BUILDDIR)
+
+Test_Url_Addr_SOURCES = \
+ Test_URL_Addr.cpp
+
+Test_Url_Addr_LDADD = \
+ $(top_builddir)/websvcs/lib/libwebsvcs.la \
+ $(ACE_BUILDDIR)/ace/libACE.la
+
+## Clean up template repositories, etc.
+clean-local:
+ -rm -f *~ *.bak *.rpo *.sym lib*.*_pure_* core core.*
+ -rm -f gcctemp.c gcctemp so_locations *.ics
+ -rm -rf cxx_repository ptrepository ti_files
+ -rm -rf templateregistry ir.out
+ -rm -rf ptrepository SunWS_cache Templates.DB
diff --git a/ACE/websvcs/tests/Test_URL_Addr.cpp b/ACE/websvcs/tests/Test_URL_Addr.cpp
new file mode 100644
index 00000000000..4f4e33d3cde
--- /dev/null
+++ b/ACE/websvcs/tests/Test_URL_Addr.cpp
@@ -0,0 +1,214 @@
+// $Id$
+
+#include "websvcs/lib/URL_Addr.h"
+#include "ace/Log_Msg.h"
+
+ACE_RCSID(WEBSVCS_Test, Test_URL_Addr, "$Id$")
+
+void test_http_addr (void);
+void test_ftp_addr (void);
+void test_mailto_addr (void);
+void test_url_addr (void);
+
+int ACE_TMAIN (int, ACE_TCHAR*[])
+{
+ test_http_addr ();
+ test_ftp_addr ();
+ test_mailto_addr ();
+ test_url_addr ();
+ return 0;
+}
+
+#define HTTP_TEST_ARRAY \
+ ACE_TEXT("http://www.cs.wustl.edu/"), \
+ ACE_TEXT("http://www.cs.wustl.edu/index.html"), \
+ ACE_TEXT("http://www.cs.wustl.edu/form?var=foo"), \
+ ACE_TEXT("http://www.notexist.com:8080/index.html"), \
+ ACE_TEXT("http://www.notexist.com:80/index.html"), \
+ ACE_TEXT("ftp://foo"), \
+ ACE_TEXT("http://www/?kkk//")
+
+#define FTP_TEST_ARRAY \
+ ACE_TEXT("ftp://www.cs.wustl.edu/"), \
+ ACE_TEXT("ftp://user@www.cs.wustl.edu/"), \
+ ACE_TEXT("ftp://user:pass@www.cs.wustl.edu/"), \
+ ACE_TEXT("ftp://user:pass@www.cs.wustl.edu/path"), \
+ ACE_TEXT("ftp://www.cs.wustl.edu"), \
+ ACE_TEXT("http://www.cs.wustl.edu/index.html")
+
+#define MAILTO_TEST_ARRAY \
+ ACE_TEXT("mailto:ace-users@cs.wustl.edu"), \
+ ACE_TEXT("mailto:majordomo@cs.wustl.edu?Subject: subscribe ace-users"), \
+ ACE_TEXT("mailto:nobody"), \
+ ACE_TEXT("http://www.cs.wustl.edu")
+
+#define URL_TEST_ARRAY \
+ ACE_TEXT("file:/etc/passwd")
+
+void test_http_addr (void)
+{
+ static const ACE_TCHAR *addresses[] = {
+ HTTP_TEST_ARRAY
+ };
+ static int naddresses = sizeof(addresses)/sizeof(addresses[0]);
+ for (int i = 0; i < naddresses; ++i)
+ {
+ ACE_HTTP_Addr addr;
+ if (addr.string_to_addr (addresses[i]) != 0)
+ {
+ ACE_ERROR ((LM_ERROR,
+ "HTTP[%d]\n"
+ " \"%s\" ERROR\n",
+ i, addresses[i]));
+ continue;
+ }
+
+ ACE_TCHAR buffer[BUFSIZ];
+ if (addr.addr_to_string (buffer, BUFSIZ, i%2) == 0)
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ "HTTP[%d]\n"
+ " \"%s\"\n"
+ " <%s>\n"
+ " <%s>\n",
+ i, addresses[i],
+ addr.get_url (),
+ buffer));
+ }
+ else
+ {
+ ACE_ERROR ((LM_ERROR,
+ "HTTP[%d]\n"
+ " \"%s\" ERROR\n",
+ i, addresses[i]));
+ }
+ }
+}
+
+void test_ftp_addr (void)
+{
+ static const ACE_TCHAR *addresses[] = {
+ FTP_TEST_ARRAY
+ };
+ static int naddresses = sizeof(addresses)/sizeof(addresses[0]);
+ for (int i = 0; i < naddresses; ++i)
+ {
+ ACE_FTP_Addr addr;
+ if (addr.string_to_addr (addresses[i]) != 0)
+ {
+ ACE_ERROR ((LM_ERROR,
+ "FTP[%d]\n"
+ " \"%s\" ERROR\n",
+ i, addresses[i]));
+ continue;
+ }
+
+ ACE_TCHAR buffer[BUFSIZ];
+ if (addr.addr_to_string (buffer, BUFSIZ, i%2) == 0)
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ "FTP[%d]\n"
+ " \"%s\"\n"
+ " <%s>\n"
+ " <%s>\n",
+ i, addresses[i],
+ addr.get_url (),
+ buffer));
+ }
+ else
+ {
+ ACE_ERROR ((LM_ERROR,
+ "FTP[%d]\n"
+ " \"%s\" ERROR\n",
+ i, addresses[i]));
+
+ }
+ }
+}
+
+void test_mailto_addr (void)
+{
+ static const ACE_TCHAR *addresses[] = {
+ MAILTO_TEST_ARRAY
+ };
+ static int naddresses = sizeof(addresses)/sizeof(addresses[0]);
+ for (int i = 0; i < naddresses; ++i)
+ {
+ ACE_Mailto_Addr addr;
+ if (addr.string_to_addr (addresses[i]) != 0)
+ {
+ ACE_ERROR ((LM_ERROR,
+ "Mailto[%d]\n"
+ " \"%s\" ERROR\n",
+ i, addresses[i]));
+ continue;
+ }
+
+ ACE_TCHAR buffer[BUFSIZ];
+ if (addr.addr_to_string (buffer, BUFSIZ, i%2) == 0)
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ "Mailto[%d]\n"
+ " \"%s\"\n"
+ " <%s>\n"
+ " <%s>\n",
+ i, addresses[i],
+ addr.get_url (),
+ buffer));
+ }
+ else
+ {
+ ACE_ERROR ((LM_ERROR,
+ "Mailto[%d]\n"
+ " \"%s\" ERROR\n",
+ i, addresses[i]));
+
+ }
+ }
+}
+
+void test_url_addr (void)
+{
+ static const ACE_TCHAR *addresses[] = {
+ HTTP_TEST_ARRAY,
+ FTP_TEST_ARRAY,
+ MAILTO_TEST_ARRAY,
+ URL_TEST_ARRAY
+ };
+ static int naddresses = sizeof(addresses)/sizeof(addresses[0]);
+ for (int i = 0; i < naddresses; ++i)
+ {
+ ACE_URL_Addr* addr =
+ ACE_URL_Addr::create_address (addresses[i]);
+ if (addr == 0)
+ {
+ ACE_ERROR ((LM_ERROR,
+ "URL[%d]\n"
+ " \"%s\" ERROR\n",
+ i, addresses[i]));
+ continue;
+ }
+
+ ACE_TCHAR buffer[BUFSIZ];
+ if (addr->addr_to_string (buffer, BUFSIZ, i%2) == 0)
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ "URL[%d]\n"
+ " \"%s\"\n"
+ " <%s>\n"
+ " <%s>\n",
+ i, addresses[i],
+ addr->get_url (),
+ buffer));
+ }
+ else
+ {
+ ACE_ERROR ((LM_ERROR,
+ "URL[%d]\n"
+ " \"%s\" ERROR\n",
+ i, addresses[i]));
+
+ }
+ }
+}
+
diff --git a/ACE/websvcs/tests/tests.mpc b/ACE/websvcs/tests/tests.mpc
new file mode 100644
index 00000000000..f4379ac3883
--- /dev/null
+++ b/ACE/websvcs/tests/tests.mpc
@@ -0,0 +1,13 @@
+// -*- MPC -*-
+// $Id$
+
+project(Websvcs Test) : aceexe {
+ exename = Test_Url_Addr
+ libs += websvcs
+ after += websvcs
+ Source_Files {
+ Test_URL_Addr.cpp
+ }
+ Header_Files {
+ }
+}