/******************************************************************************/ /* */ /* X r d C l i e n t U r l I n f o . c c */ /* */ /* Author: Fabrizio Furano (INFN Padova, 2004) */ /* Adapted from TXNetFile (root.cern.ch) originally done by */ /* Alvise Dorigo, Fabrizio Furano, INFN Padova, 2003 */ /* Revised by G. Ganis, CERN, June 2005 */ /* */ /* This file is part of the XRootD software suite. */ /* */ /* XRootD is free software: you can redistribute it and/or modify it under */ /* the terms of the GNU Lesser General Public License as published by the */ /* Free Software Foundation, either version 3 of the License, or (at your */ /* option) any later version. */ /* */ /* XRootD is distributed in the hope that it will be useful, but WITHOUT */ /* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or */ /* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public */ /* License for more details. */ /* */ /* You should have received a copy of the GNU Lesser General Public License */ /* along with XRootD in a file called COPYING.LESSER (LGPL license) and file */ /* COPYING (GPL license). If not, see . */ /* */ /* The copyright holder's institutional names and contributor's names may not */ /* be used to endorse or promote products derived from this software without */ /* specific prior written permission of the institution or contributor. */ /******************************************************************************/ ////////////////////////////////////////////////////////////////////////// // // // Class handling information about an url // // // ////////////////////////////////////////////////////////////////////////// #include "XrdClient/XrdClientDebug.hh" #include "XrdClient/XrdClientUrlInfo.hh" #include "XrdSys/XrdSysDNS.hh" #ifndef WIN32 #include #include #else #include "XrdSys/XrdWin32.hh" #endif #include #include //_____________________________________________________________________________ XrdClientUrlInfo::XrdClientUrlInfo() { // Default constructor Clear(); } //_____________________________________________________________________________ XrdClientUrlInfo::XrdClientUrlInfo(const char *url) { // Constructor from a string specifying an url or multiple urls in the // form: // [proto://][user1@]host1:port1[,[user2@]host2:port2, ... , // [userN@]hostN:portN]]/pathfile Clear(); TakeUrl(XrdOucString(url)); } //_____________________________________________________________________________ XrdClientUrlInfo::XrdClientUrlInfo(const XrdOucString &url) { // Constructor from a string specifying an url or multiple urls in the // form: // [proto://][user1@]host1:port1[,[user2@]host2:port2, ... , // [userN@]hostN:portN]]/pathfile Clear(); TakeUrl(url); } //______________________________________________________________________________ XrdClientUrlInfo::XrdClientUrlInfo(const XrdClientUrlInfo &url) { // Copy constructor Proto = url.Proto; User = url.User; Passwd = url.Passwd; Host = url.Host; HostWPort= url.HostWPort; HostAddr = url.HostAddr; Port = url.Port; File = url.File; } //_____________________________________________________________________________ void XrdClientUrlInfo::Clear() { // Set defaults Proto = ""; User = ""; Passwd = ""; Host = ""; HostWPort= ""; HostAddr = ""; Port = -1; File = "/"; } //______________________________________________________________________________ XrdClientUrlInfo& XrdClientUrlInfo::operator=(const XrdOucString &url) { // Assign url to local url. this->TakeUrl(url); return (*this); } //______________________________________________________________________________ XrdClientUrlInfo& XrdClientUrlInfo::operator=(const XrdClientUrlInfo &url) { // Assign url to local url. Proto = url.Proto; User = url.User; Passwd = url.Passwd; Host = url.Host; HostWPort= url.HostWPort; HostAddr = url.HostAddr; Port = url.Port; File = url.File; return (*this); } //_____________________________________________________________________________ void XrdClientUrlInfo::TakeUrl(XrdOucString u) { // Parse url character string and split in its different subcomponents. // Use IsValid() to check if URL is legal. // Url format: // [proto://][user[:passwd]@]host:port/pathfile // int p1 = 0, p2 = STR_NPOS, p3 = STR_NPOS, left = u.length(); Clear(); Info(XrdClientDebug::kHIDEBUG,"TakeUrl", "parsing url: " << u); if (u.length() <= 0) return; // Get protocol if ((p2 = u.find("://")) != STR_NPOS) { Proto.assign(u, p1, p2-1); Info(XrdClientDebug::kHIDEBUG,"TakeUrl", " Proto: " << Proto); // Update start of search range and remaining length p1 = p2 + 3; left = u.length() - p1; } if (left <= 0) { Clear(); return; } // Store the whole "[user[:passwd]@]host:port" thing in HostWPort if ((p2 = u.find('/', p1)) != STR_NPOS) { if (p2 > p1) { HostWPort.assign(u, p1, p2-1); // Update start of search range and remaining length p1 = p2+1; left = u.length() - p1; } } else { HostWPort.assign(u, p1); left = 0; } Info(XrdClientDebug::kHIDEBUG,"TakeUrl", " HostWPort: " << HostWPort); // Get pathfile if (left > 0) File.assign(u, p1); Info(XrdClientDebug::kHIDEBUG,"TakeUrl", " File: " << File); // // Resolve username, passwd, host and port. p1 = 0; left = HostWPort.length(); // Get user/pwd if ((p2 = HostWPort.find('@', p1)) != STR_NPOS) { p3 = HostWPort.find(':', p1); if (p3 != STR_NPOS && p3 < p2) { User.assign(HostWPort, p1, p3-1); Passwd.assign(HostWPort, p3+1, p2-1); Info(XrdClientDebug::kHIDEBUG,"TakeUrl", " Passwd: " << Passwd); } else { User.assign(HostWPort, p1, p2-1); } Info(XrdClientDebug::kHIDEBUG,"TakeUrl", " User: " << User); // Update start of search range and remaining length p1 = p2 + 1; left -= p1; } // Get host:port if ((p2 = HostWPort.find(':', p1)) != STR_NPOS ) { Host.assign(HostWPort, p1, p2-1); Port = strtol((HostWPort.c_str())+p2+1, (char **)0, 10); } else { Host.assign(HostWPort, p1); Port = 0; } Info(XrdClientDebug::kHIDEBUG,"TakeUrl", " Host: " << Host); Info(XrdClientDebug::kHIDEBUG,"TakeUrl", " Port: " << Port); } //_____________________________________________________________________________ XrdOucString XrdClientUrlInfo::GetUrl() { // Get full url // The fields might have been modified, so the full url // must be reconstructed XrdOucString s; if (Proto != "") { s = Proto; s += "://"; } if (User != "") { s += User; if (Passwd != "") { s += ":"; s += Passwd; } s += "@"; } s += Host; if ( (Host != "") && (Port > 0) ) { char buf[256]; sprintf(buf, "%d", Port); s += ":"; s += buf; } if (File != "") { s += "/"; s += File; } return s; } //_____________________________________________________________________________ void XrdClientUrlInfo::SetAddrFromHost() { struct sockaddr_in ip[2]; char buf[255], **errmsg = 0; int numaddr = XrdSysDNS::getHostAddr((char *)Host.c_str(), (struct sockaddr *)ip, 1, errmsg); if (numaddr > 0) HostAddr = inet_ntop(ip[0].sin_family, &ip[0].sin_addr, buf, sizeof(buf)); }