Skip to content

Commit

Permalink
Add support for paths in Utils::splitHost()
Browse files Browse the repository at this point in the history
If a path was present after the hostname, and there was no port
specified, an incorrect hostname would be returned to the caller.
  • Loading branch information
Colin Ward authored and hitman-codehq committed Jun 6, 2024
1 parent 2311fb3 commit 120429e
Show file tree
Hide file tree
Showing 3 changed files with 79 additions and 30 deletions.
28 changes: 28 additions & 0 deletions Tests/T_Utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -466,6 +466,34 @@ int main()
Result = Utils::StringToInt("", &Value);
test(Result == KErrCorrupt);

/* Test #16: Utils::splitHost() tests */

Test.Next("Utils::splitHost() tests");

std::string Server;
int PathOffset;
unsigned short Port;

test(Utils::splitHost("www.example.com", Server, Port, 80) == KErrNone);
test(Server == "www.example.com");
test(Port == 80);

test(Utils::splitHost("www.example.com:8080", Server, Port, 80) == KErrNone);
test(Server == "www.example.com");
test(Port == 8080);

test(Utils::splitHost("", Server, Port, 80) == KErrNotFound);

PathOffset = Utils::splitHost("www.example.com/path", Server, Port, 80);
test(Server == "www.example.com");
test(Port == 80);
test(PathOffset == 16);

PathOffset = Utils::splitHost("www.example.com:8080/path", Server, Port, 80);
test(Server == "www.example.com");
test(Port == 8080);
test(PathOffset == 21);

/* Clean up after ourselves */

Result = g_oFileUtils.deleteFile("TimeFile.txt");
Expand Down
79 changes: 50 additions & 29 deletions Utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3083,56 +3083,77 @@ TInt Utils::setProtection(const char *a_pccFileName, TUint a_uiAttributes)

/**
* Split a host into its hostname and port components.
* This function parses a string in the format hostname:port and extracts the two components into a string
* and an unsigned short variable respectively. The port is optional and if not present, a default value will
* be used. It is considered an error for the hostname to not be present.
* This function parses a string in the format hostname:port/path and extracts the first two components into a string
* and an unsigned short variable respectively. The port is optional and if not present, a default value will be used.
* It is considered an error for the hostname to not be present.
*
* If a path follows the hostname and port, it will be discarded, but its offset will be returned to indicate its
* presence.
*
* @date Friday 10-May-2024 6:03 am, Code HQ Tokyo Tsukuda
* @param a_pccHost The host to parse
* @param a_roServer The string into which to place the extracted hostname
* @param a_rusPort The unsigned short into which to place the extracted port
* @param a_usDefaultPort The port to be used if no port is specified
* @return KErrNone if successful
* @return KErrNone or the positive path offset if successful
* @return KErrNotFound if the hostname was not present
*/

int Utils::splitHost(const char *a_pccHost, std::string &a_roServer, unsigned short &a_rusPort, unsigned short a_usDefaultPort)
int Utils::splitHost(const char *a_host, std::string &a_server, unsigned short &a_port, unsigned short a_defaultPort)
{
int serverLength, portLength, port, retVal;
TLex lex(a_pccHost, static_cast<int>(strlen(a_pccHost)));
int hostLength, pathLength, serverLength, portLength, port, retVal;
TLex hostLex(a_host, static_cast<int>(strlen(a_host)));

retVal = KErrNone;
retVal = KErrNotFound;

/* Extract the server name and port number from the host passed in and, if a port was specified, */
/* convert it and check its validity */
lex.SetWhitespace(":");
/* Extract the server name and port number from the complete URL passed in */
hostLex.SetWhitespace("/");

const char *serverString = lex.NextToken(&serverLength);
const char *portString = lex.NextToken(&portLength);
const char *hostString = hostLex.NextToken(&hostLength);

if (serverString != nullptr)
if (hostString != nullptr)
{
a_roServer = std::string(serverString, serverLength);
std::string host(hostString, hostLength);
TLex lex(host.c_str(), hostLength);

/* Extract the server name and port number from the host passed in and, if a port was specified, */
/* convert it and check its validity */
lex.SetWhitespace(":");

/* The port string is optional so only parse if it is there, and use the default value if it is missing */
/* or invalid */
a_rusPort = a_usDefaultPort;
const char *serverString = lex.NextToken(&serverLength);
const char *portString = lex.NextToken(&portLength);

if (portString)
if (serverString != nullptr)
{
if (Utils::StringToInt(portString, &port) == KErrNone)
{
a_rusPort = static_cast<unsigned short>(port);
}
else
retVal = KErrNone;

a_server = std::string(serverString, serverLength);

/* The port string is optional so only parse if it is there, and use the default value if it is missing */
/* or invalid */
a_port = a_defaultPort;

if (portString)
{
Utils::info("Utils::splitURL() => Specified port \"%s\" is invalid, using default port %d", portString, a_rusPort);
if (Utils::StringToInt(portString, &port) == KErrNone)
{
a_port = static_cast<unsigned short>(port);
}
else
{
Utils::info("Utils::splitURL() => Specified port \"%s\" is invalid, using default port %d", portString, a_port);
}
}
}
}
else
{
retVal = KErrNotFound;

/* If a path follows the server name and port, it will be discarded, but return to the client the fact that */
/* it is there, by returning its offset in the URL */
const char *pathString = hostLex.NextToken(&pathLength);

if (pathString != nullptr)
{
retVal = static_cast<int>(pathString - a_host);
}
}

return retVal;
Expand Down
2 changes: 1 addition & 1 deletion Utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ class Utils

static TInt setProtection(const char *a_pccFileName, TUint a_uiAttributes);

static int splitHost(const char *a_pccHost, std::string &a_roServer, unsigned short &a_rusPort, unsigned short a_usDefaultPort = 80);
static int splitHost(const char *a_host, std::string &a_server, unsigned short &a_port, unsigned short a_defaultPort = 80);

static char *StripDags(char *a_pcLine, TInt *a_piLength);

Expand Down

0 comments on commit 120429e

Please sign in to comment.