00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 #include <algorithm>
00022 #include <boost/lexical_cast.hpp>
00023 #include <boost/algorithm/string/case_conv.hpp>
00024 #include <boost/algorithm/string/predicate.hpp>
00025 #include <boost/algorithm/string/replace.hpp>
00026 #include "weUrl.h"
00027 
00028 using namespace boost::algorithm;
00029 
00030 #ifndef __DOXYGEN__
00031 static string& fixDoubleSlash(string& req)
00032 {
00033     string path, vals;
00034     size_t pos;
00035 
00036     pos = req.find('?');
00037     path = req.substr(0, pos);
00038     if (pos != string::npos) {
00039         vals = req.substr(pos);
00040     }
00041     else {
00042         vals = "";
00043     }
00044     replace_all(path, "/./", "/");
00045     while (path.find("//") != string::npos) {
00046         replace_all(path, "//", "/");
00047     }
00048     req = path + vals;
00049     return req;
00050 }
00051 #endif //__DOXYGEN__
00052 
00053 WeURL::WeURL()
00054 {
00055     port = -1;
00056     host = "";
00057     request = "";
00058     valid = false;
00059 }
00060 
00061 WeURL::WeURL( const string url )
00062 {
00063     port = -1;
00064     host = "";
00065     request = "";
00066     valid = false;
00067     Assign(url);
00068 }
00069 
00070 WeURL::WeURL( const WeURL& url )
00071 {
00072     protocol = url.protocol;
00073     host = url.host;
00074     port = url.port;
00075     request = url.request;
00076     params = url.params;
00077     username = url.username;
00078     password = url.password;
00079     valid = url.valid;
00080 }
00081 
00082 WeURL::~WeURL()
00083 {
00084     
00085 }
00086 
00087 WeURL& WeURL::operator=( const WeURL& url )
00088 {
00089     protocol = url.protocol;
00090     host = url.host;
00091     port = url.port;
00092     request = url.request;
00093     params = url.params;
00094     username = url.username;
00095     password = url.password;
00096     valid = url.valid;
00097     return *this;
00098 }
00099 
00100 string& WeURL::ToString(bool noDefPort )
00101 {
00102     string *retval = new string;
00103 
00104     *retval = protocol + "://";
00105     if (!username.empty() || !password.empty()) {
00106         *retval += username + ':' + password +'@';
00107     }
00108     *retval += host;
00109     if (noDefPort && ((protocol == "http" && port == 80) || (protocol == "https" && port == 443))) {
00110         
00111     }
00112     else if (port > 0 && port < 65536) {
00113         *retval += ':';
00114         *retval += boost::lexical_cast<std::string>(port);
00115     }
00116     *retval += request;
00117     if (!params.empty()) {
00118         *retval += "?";
00119         *retval += params;
00120     }
00121     return *retval;
00122 }
00123 
00124 void WeURL::Assign( string url )
00125 {
00126     string temp = url;
00127     size_t pos;
00128 
00129     
00130     pos = temp.find(':');
00131     if (pos == string::npos) {
00132         valid = false;
00133         return;
00134     }
00135 
00136     protocol = temp.substr(0, pos);
00137     to_lower(protocol);
00138     temp = temp.substr(pos+1);
00139 
00140     if ((temp[0] != '/') || (temp[1] != '/')) {
00141         valid = false;
00142         return;
00143     }
00144 
00145     temp = temp.substr(2);      
00146     pos = temp.find('/');
00147     if (pos == string::npos) {
00148         request = "/";             
00149         temp = temp.substr(0, pos);            
00150     }
00151     else {
00152         request = temp.substr(pos);        
00153         temp = temp.substr(0, pos);            
00154     }
00155 
00156     if (pos == 0) {
00157         valid = false;
00158         return;
00159     }
00160 
00161     
00162     pos = temp.find('@');
00163     if(pos != string::npos)  {
00164         string szAuth = temp.substr(0,pos);  
00165         temp = temp.substr(pos+1);         
00166 
00167         pos = szAuth.find(':');
00168         if( pos != string::npos ) {
00169             password = szAuth.substr(pos+1);
00170             username = szAuth.substr(0,pos);
00171         }
00172         else
00173             username = szAuth;
00174     }
00175 
00176     
00177     pos = temp.find(':');
00178     if( pos != string::npos ) {
00179         port = atoi(temp.substr(pos+1).c_str());
00180         host = temp.substr(0,pos);
00181     }
00182     else {
00183         host = temp;
00184         if( protocol == "http" )
00185             port = 80;
00186         else if( protocol == "https" )
00187             port = 443;
00188         else
00189             port = 80;
00190     }
00191 
00192     while (starts_with(request, "./"))
00193     {
00194         request = request.substr(2);
00195     }
00196     fixDoubleSlash(request);
00197     pos = request.find('?');
00198     if (pos != string::npos) {
00199         params = request.substr(pos + 1);
00200         request = request.substr(0, pos);
00201     }
00202     else {
00203         params.clear();
00204     }
00205     valid = true;
00206 }
00207 
00208 void WeURL::Restore( string url, WeURL* base  )
00209 {
00210     string    temp;
00211     size_t    pos;
00212 
00213     if (base == NULL) {
00214         base = this;
00215     }
00216     
00217     pos = url.find("://");
00218     if (pos == string::npos) {
00219         
00220         protocol = base->protocol;
00221         to_lower(protocol);
00222         username = base->username;
00223         password = base->password;
00224         host = base->host;
00225         port = base->port;
00226         if (starts_with(url, "/")) {
00227             request = url;
00228         }
00229         else {
00230             pos = base->request.find('?');
00231             temp = base->request.substr(0, pos);
00232             pos = temp.rfind('/');
00233             temp = temp.substr(0, pos);
00234             
00235             while (starts_with(url, "./"))
00236             {
00237                 url = url.substr(2);
00238             }
00239             
00240             while (starts_with(url, "../"))
00241             {
00242                 pos = temp.rfind('/');
00243                 if (pos == string::npos) {
00244                     break;
00245                 }
00246                 temp = temp.substr(0, pos);
00247                 url = url.substr(3);
00248                 if (starts_with(url, "./"))
00249                 {
00250                     url = url.substr(2);
00251                 }
00252             }
00253             temp += '/';
00254             temp += url;
00255             request = temp;
00256             fixDoubleSlash(request);
00257             pos = request.find('?');
00258             if (pos != string::npos) {
00259                 params = request.substr(pos + 1);
00260                 request = request.substr(0, pos);
00261             }
00262             else {
00263                 params.clear();
00264             }
00265         }
00266         valid = true;
00267     }
00268     else {
00269         Assign(url);
00270     }
00271 }
00272 
00273 bool WeURL::IsValid( void )
00274 {
00275     bool retval = (valid && !host.empty() && !request.empty() && port > 0 && port < 65535);
00276     valid = retval;
00277     return retval;
00278 }