diff options
Diffstat (limited to 'ACE/apps/JAWS2/HTTPU/parse_url.cpp')
-rw-r--r-- | ACE/apps/JAWS2/HTTPU/parse_url.cpp | 322 |
1 files changed, 322 insertions, 0 deletions
diff --git a/ACE/apps/JAWS2/HTTPU/parse_url.cpp b/ACE/apps/JAWS2/HTTPU/parse_url.cpp new file mode 100644 index 00000000000..c1c753d0784 --- /dev/null +++ b/ACE/apps/JAWS2/HTTPU/parse_url.cpp @@ -0,0 +1,322 @@ +// $Id$ + +#include "ace/OS_NS_string.h" +#include "ace/OS_NS_stdlib.h" +#include "ace/Log_Msg.h" +#include "HTTPU/parse_url.h" + +HTTP_Parse_URL::HTTP_Parse_URL (const char *url) + : url_ (0), + scheme_ (0), + user_ (0), + passwd_ (0), + host_ (0), + port_ (-1), + url_path_ (0), + error_ (NONE), + is_cgi_ (0) +{ + this->init (url); +} + +HTTP_Parse_URL::~HTTP_Parse_URL (void) +{ + if (this->url_) + ACE_OS::free (this->url_); + this->url_ = 0; + this->scheme_ = 0; + this->user_ = 0; + this->passwd_ = 0; + this->host_ = 0; + this->port_ = -1; + this->url_path_ = 0; +} + + +void +HTTP_Parse_URL::init( const char *url ) +{ + // Should really reset completely and cleanly here before + // doing anything else! + if ( url == 0 ) + return; + + if ( url_ ) + ACE_OS::free( url_ ); + + url_ = ACE_OS::strdup( url ); + if ( url_ == 0 ) + { + error_ = STRDUP; + return; + } + + if (ACE_OS::strlen (this->url_) > 3 && ACE_OS::strstr ("://", this->url_)) + { + // Parse it out completely. Figure out what it is later. + parse_url(); + } + else + { + this->url_path_ = this->url_; + this->is_cgi (this->url_path_); + } +} + + +void +HTTP_Parse_URL::parse_url (void) +{ + char *p = this->url_; + + char *q; + if ((q = ACE_OS::strchr (this->url_, '\r')) + || (q = ACE_OS::strchr (this->url_, '\n'))) + *q = '\0'; + + this->parse_scheme (p); + if (*p == '\0') + { + this->error_ = SCHEME; + return; + } + + // Parse past "//" + if (*p != '/' || *(p+1) != '/') + { + this->error_ = SLASHSLASH; + return; + } + p += 2; + + this->parse_host (p); + + while (*p == '/') + p++; + + if (*p == '\0') + return; + + this->url_path_ = p; + this->is_cgi (this->url_path_); +} + +void +HTTP_Parse_URL::parse_scheme (char *&p) +{ + // Parse the scheme. The scheme is delimited by a ':'. + if (*p != '\0') + { + this->scheme_ = p++; + for (;;) + { + switch (*p) + { + case '\0': + break; + case ':': + *p++ = '\0'; + break; + default: + p++; + continue; + } + break; + } + } +} + +void +HTTP_Parse_URL::parse_host (char *&p) +{ + // Parse user, password, host, port + if (*p == '/' || *p == '\0') + { + this->set_port_from_scheme (); + return; + } + + char *at = 0; + char *colon1 = 0; + char *colon2 = 0; + char *q = p; + while (*q != '\0') + { + if (*q == '/') + { + *q = '\0'; + q++; + break; + } + if (*q == ':') + { + if (colon1 == 0) + { + if (at != 0 && colon2 == 0) + colon2 = q; + else + colon1 = q; + } + else + { + if (at != 0 && colon2 == 0) + colon2 = q; + } + } + if (*q == '@') + { + if (at == 0) + at = q; + } + q++; + } + + // no user, no port + if (at == 0 && colon1 == 0) + { + if (*p != '\0' && *p != '/') + this->host_ = p; + } + + // no user, port + else if (at == 0 && colon1 != 0) + { + if (p != colon1) + this->host_ = p; + *colon1++ = '\0'; + this->port_ = ACE_OS::atoi (colon1); + } + + // user, no passwd, no port + else if (at != 0 && colon1 == 0 && colon2 == 0) + { + this->user_ = p; + *at++ = '\0'; + if (*at != '\0' && *at != '/') + this->host_ = at; + } + + // user, no passwd, port + else if (at != 0 && colon1 == 0 && colon2 != 0) + { + this->user_ = p; + *at++ = '\0'; + if (at != colon2) + this->host_ = at; + *colon2++ = '\0'; + this->port_ = ACE_OS::atoi (colon2); + } + + // user, passwd, no port + else if (at != 0 && colon1 != 0 && colon2 == 0) + { + this->user_ = p; + *colon1++ = '\0'; + this->passwd_ = colon1; + *at++ = '\0'; + if (*at != '\0') + this->host_ = at; + } + + // user, passwd, and port + else if (at != 0 && colon1 != 0 && colon2 != 0) + { + this->user_ = p; + *colon1++ = '\0'; + this->passwd_ = colon1; + *at++ = '\0'; + if (at != colon2) + this->host_ = at; + *colon2++ = '\0'; + this->port_ = ACE_OS::atoi (colon2); + } + + // impossible! + else + { + ACE_ERROR ((LM_ERROR, "uh oh!\n")); + p = q; + return; + } + + this->set_port_from_scheme (); + p = q; +} + +void +HTTP_Parse_URL::set_port_from_scheme (void) +{ + if (ACE_OS::strcmp (this->scheme_, "ftp") == 0) + { + if (this->port_ == -1) + this->port_ = 21; + if (this->user_ == 0) + { + this->user_ = "anonymous"; + + // *** need something better here + this->passwd_ = "a@b.c"; + } + } + else if (ACE_OS::strcmp (this->scheme_, "http") == 0) + { + if (this->port_ == -1) + this->port_ = 80; + } +} + +const char * +HTTP_Parse_URL::scheme (void) const +{ + return this->scheme_; +} + +const char * +HTTP_Parse_URL::user (void) const +{ + return this->user_; +} + +const char * +HTTP_Parse_URL::passwd (void) const +{ + return this->passwd_; +} + +const char * +HTTP_Parse_URL::host (void) const +{ + return this->host_; +} + +int +HTTP_Parse_URL::port (void) const +{ + return this->port_; +} + +const char * +HTTP_Parse_URL::url_path (void) const +{ + return this->url_path_ ? this->url_path_ : ""; +} + +void +HTTP_Parse_URL::is_cgi (const char *path) +{ + int yes; + + yes = (ACE_OS::strchr (path, '?') != 0); + if (!yes && (ACE_OS::strlen (path) >= 3)) + yes = (ACE_OS::strstr (path, "cgi") != 0); + if (!yes) + yes = (ACE_OS::strstr (path, "asp") != 0); + + this->is_cgi_ = yes; +} + +int +HTTP_Parse_URL::is_cgi (void) const +{ + return this->is_cgi_; +} |