Changes for the standard URL parsing. Added SetRelativePath. Cleaned up the deletions (all thru nsCRT now) Added functionality for Query and Ref portions of the Path. Added DirFile function to nsIURL to allow just Directory and the Filename. Misc. cleanups as well.

This commit is contained in:
gagan%netscape.com 1999-07-22 21:14:51 +00:00
Родитель 2a0eda4e69
Коммит b44058b222
15 изменённых файлов: 800 добавлений и 261 удалений

Просмотреть файл

@ -116,6 +116,15 @@ interface nsIURI : nsISupports
* channel is opened the URI may get redirected to a new location. * channel is opened the URI may get redirected to a new location.
*/ */
nsIURI Clone(); nsIURI Clone();
/**
* Sets the given string to be a relative path for this URL, and
* changes this to read relative. Thus for example- if this =
* http://foo.com/bar/index.html, then calling SetRelativePath("/baz") will
* change this to http://foo.com/baz and calling it with "baz" will
* change this to http://foo.com/bar/baz.
*/
void SetRelativePath(in string i_RelativePath);
}; };
%{C++ %{C++

Просмотреть файл

@ -52,6 +52,12 @@ interface nsIURL : nsIURI
*/ */
attribute string FileName; attribute string FileName;
/**
* Returns the parameters specified after the ; in the URL.
*
attribute string Param;
*/
/** /**
* Returns the query portion (the part after the "?") of the URL. * Returns the query portion (the part after the "?") of the URL.
* If there isn't one, an empty string is returned. * If there isn't one, an empty string is returned.
@ -64,6 +70,10 @@ interface nsIURL : nsIURI
*/ */
attribute string Ref; attribute string Ref;
/**
* Returns the Directory + "/" + Filename. Just a convenience function
*/
void DirFile(out string o_DirFile);
}; };
%{C++ %{C++

Просмотреть файл

@ -33,7 +33,7 @@ CPP_OBJS = \
.\$(OBJDIR)\nsIOService.obj \ .\$(OBJDIR)\nsIOService.obj \
.\$(OBJDIR)\nsSocketTransport.obj \ .\$(OBJDIR)\nsSocketTransport.obj \
.\$(OBJDIR)\nsSocketTransportService.obj \ .\$(OBJDIR)\nsSocketTransportService.obj \
.\$(OBJDIR)\nsStandardUrl.obj \ .\$(OBJDIR)\nsStdURL.obj \
.\$(OBJDIR)\nsSimpleURI.obj \ .\$(OBJDIR)\nsSimpleURI.obj \
.\$(OBJDIR)\nsNetModuleMgr.obj \ .\$(OBJDIR)\nsNetModuleMgr.obj \
.\$(OBJDIR)\nsNetModRegEntry.obj \ .\$(OBJDIR)\nsNetModRegEntry.obj \

Просмотреть файл

@ -223,4 +223,3 @@ nsSimpleURI::Create(nsISupports *aOuter, REFNSIID aIID, void **aResult)
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////

Просмотреть файл

@ -68,6 +68,11 @@ public:
/* nsIURI Clone (); */ /* nsIURI Clone (); */
NS_IMETHOD Clone(nsIURI **_retval); NS_IMETHOD Clone(nsIURI **_retval);
/* void SetRelativePath (in string i_RelativePath); */
NS_IMETHOD SetRelativePath(const char *i_RelativePath) {
NS_ASSERTION(PR_FALSE, "This is meaningless in hack context!");
return NS_ERROR_FAILURE;};
//////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////
// nsSimpleURI methods: // nsSimpleURI methods:

Просмотреть файл

@ -28,7 +28,24 @@ static NS_DEFINE_CID(kStdURLCID, NS_STANDARDURL_CID);
static NS_DEFINE_CID(kThisStdURLImplementationCID, static NS_DEFINE_CID(kThisStdURLImplementationCID,
NS_THIS_STANDARDURL_IMPLEMENTATION_CID); NS_THIS_STANDARDURL_IMPLEMENTATION_CID);
#define CRTFREEIF(x) \
if (x) \
PR_BEGIN_MACRO \
nsCRT::free(x); \
x = 0; \
PR_END_MACRO
PRInt32 ExtractPortFrom(char* src, int start, int length); PRInt32 ExtractPortFrom(char* src, int start, int length);
void ReplaceDotMess(char* io_Path);
class nsParsePath
{
public:
nsParsePath(nsStdURL* i_URL): m_URL(i_URL) {}
virtual ~nsParsePath() {m_URL->ParsePath();}
private:
nsStdURL* m_URL;
};
nsStdURL::nsStdURL(const char* i_Spec, nsISupports* outer) nsStdURL::nsStdURL(const char* i_Spec, nsISupports* outer)
: mScheme(nsnull), : mScheme(nsnull),
@ -47,53 +64,32 @@ nsStdURL::nsStdURL(const char* i_Spec, nsISupports* outer)
Parse(); Parse();
} }
nsStdURL::nsStdURL(const nsStdURL& otherURL)
: mPort(otherURL.mPort)
{
mSpec = otherURL.mSpec ? nsCRT::strdup(otherURL.mSpec) : nsnull;
mScheme = otherURL.mScheme ? nsCRT::strdup(otherURL.mScheme) : nsnull;
mPreHost = otherURL.mPreHost ? nsCRT::strdup(otherURL.mPreHost) : nsnull;
mHost = otherURL.mHost ? nsCRT::strdup(otherURL.mHost) : nsnull;
mPath = otherURL.mPath ? nsCRT::strdup(otherURL.mPath) : nsnull;
mDirectory = otherURL.mDirectory ? nsCRT::strdup(otherURL.mDirectory) : nsnull;
mFileName = otherURL.mFileName ? nsCRT::strdup(otherURL.mFileName) : nsnull;
mQuery = otherURL.mQuery ? nsCRT::strdup(otherURL.mQuery) : nsnull;
mRef= otherURL.mRef ? nsCRT::strdup(otherURL.mRef) : nsnull;
NS_INIT_AGGREGATED(nsnull); // Todo! How?
}
nsStdURL::~nsStdURL() nsStdURL::~nsStdURL()
{ {
if (mScheme) CRTFREEIF(mScheme);
{ CRTFREEIF(mPreHost);
delete[] mScheme; CRTFREEIF(mHost);
mScheme = 0; CRTFREEIF(mPath);
} CRTFREEIF(mRef);
if (mPreHost) CRTFREEIF(mQuery);
{ CRTFREEIF(mSpec);
delete[] mPreHost; CRTFREEIF(mDirectory);
mPreHost = 0; CRTFREEIF(mFileName);
}
if (mHost)
{
delete[] mHost;
mHost = 0;
}
if (mPath)
{
delete[] mPath;
mPath = 0;
}
if (mRef)
{
delete[] mRef;
mRef = 0;
}
if (mQuery)
{
delete[] mQuery;
mQuery = 0;
}
if (mSpec)
{
delete[] mSpec;
mSpec = 0;
}
if (mDirectory)
{
delete[] mDirectory;
mDirectory = 0;
}
if (mFileName)
{
delete[] mFileName;
mFileName = 0;
}
} }
NS_IMPL_AGGREGATED(nsStdURL); NS_IMPL_AGGREGATED(nsStdURL);
@ -130,14 +126,10 @@ nsStdURL::Equals(nsIURI *i_OtherURI, PRBool *o_Equals)
NS_IMETHODIMP NS_IMETHODIMP
nsStdURL::Clone(nsIURI **o_URI) nsStdURL::Clone(nsIURI **o_URI)
{ {
//TODO replace with a copy constructor that maps everything instead of creating it afresh... nsStdURL* url = new nsStdURL(*this); /// TODO check outer?
nsStdURL* url = new nsStdURL(mSpec); /// TODO check outer?
if (url == nsnull) if (url == nsnull)
return NS_ERROR_OUT_OF_MEMORY; return NS_ERROR_OUT_OF_MEMORY;
nsresult rv= NS_OK; nsresult rv= NS_OK;
if (mSpec)
rv = url->Parse(); // Will build the elements again.
*o_URI = url; *o_URI = url;
NS_ADDREF(url); NS_ADDREF(url);
@ -147,6 +139,9 @@ nsStdURL::Clone(nsIURI **o_URI)
nsresult nsresult
nsStdURL::Parse(void) nsStdURL::Parse(void)
{ {
// Parse the path into its individual elements
// when we are done from here.
nsParsePath pp(this);
NS_PRECONDITION( (nsnull != mSpec), "Parse called on empty url!"); NS_PRECONDITION( (nsnull != mSpec), "Parse called on empty url!");
if (!mSpec) if (!mSpec)
{ {
@ -167,20 +162,20 @@ nsStdURL::Parse(void)
// If the URL starts with a slash then everything is a path // If the URL starts with a slash then everything is a path
if (brk == mSpec) if (brk == mSpec)
{ {
ExtractString(&mPath, 0, len); ExtractString(mSpec, &mPath, 0, len);
return NS_OK; return NS_OK;
} }
else // The first part is host, so its host/path else // The first part is host, so its host/path
{ {
ExtractString(&mHost, 0, (brk - mSpec)); ExtractString(mSpec, &mHost, 0, (brk - mSpec));
ExtractString(&mPath, (brk - mSpec), (len - (brk - mSpec))); ExtractString(mSpec, &mPath, (brk - mSpec), (len - (brk - mSpec)));
return NS_OK; return NS_OK;
} }
break; break;
case ':' : case ':' :
if (*(brk+1) == '/') if (*(brk+1) == '/')
{ {
ExtractString(&mScheme, 0, (brk - mSpec)); ExtractString(mSpec, &mScheme, 0, (brk - mSpec));
if (*(brk+2) == '/') // e.g. http:// if (*(brk+2) == '/') // e.g. http://
// If the first colon is followed by // then its definitely a spec // If the first colon is followed by // then its definitely a spec
@ -192,9 +187,9 @@ nsStdURL::Parse(void)
switch (*brk) switch (*brk)
{ {
case '/' : // standard case- http://host/path case '/' : // standard case- http://host/path
ExtractString(&mHost, ExtractString(mSpec, &mHost,
(lastbrk - mSpec), (brk - lastbrk)); (lastbrk - mSpec), (brk - lastbrk));
ExtractString(&mPath, ExtractString(mSpec, &mPath,
(brk - mSpec), (len - (brk - mSpec))); (brk - mSpec), (len - (brk - mSpec)));
return NS_OK; return NS_OK;
break; break;
@ -207,17 +202,17 @@ nsStdURL::Parse(void)
char* atSign = PL_strchr(brk, '@'); char* atSign = PL_strchr(brk, '@');
if (atSign) if (atSign)
{ {
ExtractString(&mPreHost, ExtractString(mSpec, &mPreHost,
(lastbrk - mSpec), (atSign - lastbrk)); (lastbrk - mSpec), (atSign - lastbrk));
brk = PL_strpbrk(atSign+1, "/:"); brk = PL_strpbrk(atSign+1, "/:");
if (brk) // http://user:pass@host:port/path or http://user:pass@host/path if (brk) // http://user:pass@host:port/path or http://user:pass@host/path
{ {
ExtractString(&mHost, ExtractString(mSpec, &mHost,
(atSign+1 - mSpec), (atSign+1 - mSpec),
(brk - (atSign+1))); (brk - (atSign+1)));
if (*brk == '/') if (*brk == '/')
{ {
ExtractString(&mPath, ExtractString(mSpec, &mPath,
(brk - mSpec), (brk - mSpec),
len - (brk - mSpec)); len - (brk - mSpec));
return NS_OK; return NS_OK;
@ -229,7 +224,7 @@ nsStdURL::Parse(void)
if (brk) // http://user:pass@host:port/path if (brk) // http://user:pass@host:port/path
{ {
mPort = ExtractPortFrom(mSpec, (lastbrk - mSpec), (brk-lastbrk)); mPort = ExtractPortFrom(mSpec, (lastbrk - mSpec), (brk-lastbrk));
ExtractString(&mPath, (brk-mSpec), len - (brk-mSpec)); ExtractString(mSpec, &mPath, (brk-mSpec), len - (brk-mSpec));
return NS_OK; return NS_OK;
} }
else // http://user:pass@host:port else // http://user:pass@host:port
@ -242,7 +237,7 @@ nsStdURL::Parse(void)
} }
else // its just http://user:pass@host else // its just http://user:pass@host
{ {
ExtractString(&mHost, ExtractString(mSpec, &mHost,
(atSign+1 - mSpec), (atSign+1 - mSpec),
len - (atSign+1 - mSpec)); len - (atSign+1 - mSpec));
return NS_OK; return NS_OK;
@ -250,7 +245,7 @@ nsStdURL::Parse(void)
} }
else // definitely the port option, i.e. http://host:port/path else // definitely the port option, i.e. http://host:port/path
{ {
ExtractString(&mHost, ExtractString(mSpec, &mHost,
(lastbrk-mSpec), (lastbrk-mSpec),
(brk-lastbrk)); (brk-lastbrk));
lastbrk = brk+1; lastbrk = brk+1;
@ -258,7 +253,7 @@ nsStdURL::Parse(void)
if (brk) // http://host:port/path if (brk) // http://host:port/path
{ {
mPort = ExtractPortFrom(mSpec, (lastbrk-mSpec),(brk-lastbrk)); mPort = ExtractPortFrom(mSpec, (lastbrk-mSpec),(brk-lastbrk));
ExtractString(&mPath, ExtractString(mSpec, &mPath,
(brk-mSpec), (brk-mSpec),
len - (brk-mSpec)); len - (brk-mSpec));
return NS_OK; return NS_OK;
@ -274,13 +269,13 @@ nsStdURL::Parse(void)
case '@' : case '@' :
// http://user@host... // http://user@host...
{ {
ExtractString(&mPreHost, ExtractString(mSpec, &mPreHost,
(lastbrk-mSpec), (brk-lastbrk)); (lastbrk-mSpec), (brk-lastbrk));
lastbrk = brk+1; lastbrk = brk+1;
brk = PL_strpbrk(lastbrk, ":/"); brk = PL_strpbrk(lastbrk, ":/");
if (brk) if (brk)
{ {
ExtractString(&mHost, ExtractString(mSpec, &mHost,
(lastbrk-mSpec), (brk - lastbrk)); (lastbrk-mSpec), (brk - lastbrk));
if (*brk == ':') // http://user@host:port... if (*brk == ':') // http://user@host:port...
{ {
@ -289,7 +284,7 @@ nsStdURL::Parse(void)
if (brk) // http://user@host:port/path if (brk) // http://user@host:port/path
{ {
mPort = ExtractPortFrom(mSpec, (lastbrk-mSpec),(brk-lastbrk)); mPort = ExtractPortFrom(mSpec, (lastbrk-mSpec),(brk-lastbrk));
ExtractString(&mPath, ExtractString(mSpec, &mPath,
(brk-mSpec), (brk-mSpec),
len - (brk-mSpec)); len - (brk-mSpec));
return NS_OK; return NS_OK;
@ -303,7 +298,7 @@ nsStdURL::Parse(void)
} }
else // (*brk == '/') so no port just path i.e. http://user@host/path else // (*brk == '/') so no port just path i.e. http://user@host/path
{ {
ExtractString(&mPath, ExtractString(mSpec, &mPath,
(brk - mSpec), (brk - mSpec),
len - (brk - mSpec)); len - (brk - mSpec));
return NS_OK; return NS_OK;
@ -311,7 +306,7 @@ nsStdURL::Parse(void)
} }
else // its just http://user@host else // its just http://user@host
{ {
ExtractString(&mHost, ExtractString(mSpec, &mHost,
(lastbrk+1 - mSpec), len - (lastbrk+1 - mSpec)); (lastbrk+1 - mSpec), len - (lastbrk+1 - mSpec));
return NS_OK; return NS_OK;
} }
@ -325,7 +320,7 @@ nsStdURL::Parse(void)
} }
else // everything else is a host, as in http://host else // everything else is a host, as in http://host
{ {
ExtractString(&mHost, ExtractString(mSpec, &mHost,
(lastbrk - mSpec), (lastbrk - mSpec),
len - (lastbrk - mSpec)); len - (lastbrk - mSpec));
return NS_OK; return NS_OK;
@ -334,89 +329,134 @@ nsStdURL::Parse(void)
} }
else // This is a no // path alone case like file:/path, there is never a prehost/host in this case. else // This is a no // path alone case like file:/path, there is never a prehost/host in this case.
{ {
ExtractString(&mPath, (brk-mSpec+1), len - (brk-mSpec+1)); ExtractString(mSpec, &mPath, (brk-mSpec+1), len - (brk-mSpec+1));
return NS_OK; return NS_OK;
} }
} }
else // host:port... else // scheme:host or host:port...
{ {
ExtractString(&mHost, 0, (brk - mSpec));
lastbrk = brk+1; lastbrk = brk+1;
brk = PL_strpbrk(lastbrk, delimiters);
if (brk)
{
switch (*brk)
{
case '/' : // The path, so its host:port/path
mPort = ExtractPortFrom(mSpec, lastbrk-mSpec, brk-lastbrk);
ExtractString(&mPath, brk- mSpec, len - (brk-mSpec));
return NS_OK;
break;
case ':' :
return NS_ERROR_FAILURE;//TODO NS_ERROR_URL_PARSING;
break;
case '@' :
// This is a special case of user:pass@host... so
// Cleanout our earliar knowledge of host
ExtractString(&mHost, -1, -1);
ExtractString(&mPreHost, 0, (brk-mSpec)); if ((*lastbrk >= '0') && (*lastbrk <= '9')) //host:port...
lastbrk = brk+1; {
brk = PL_strpbrk(lastbrk, ":/"); ExtractString(mSpec, &mHost, 0, (brk - mSpec));
if (brk) brk = PL_strpbrk(lastbrk, delimiters);
{ if (brk)
ExtractString(&mHost, {
(lastbrk-mSpec), (brk-lastbrk)); switch (*brk)
if (*brk == ':') // user:pass@host:port... {
case '/' : // The path, so its host:port/path
mPort = ExtractPortFrom(mSpec, lastbrk-mSpec, brk-lastbrk);
ExtractString(mSpec, &mPath, brk- mSpec, len - (brk-mSpec));
return NS_OK;
break;
case ':' :
return NS_ERROR_FAILURE;//TODO NS_ERROR_URL_PARSING;
break;
case '@' :
// This is a special case of user:pass@host... so
// Cleanout our earliar knowledge of host
ExtractString(mSpec, &mHost, -1, -1);
ExtractString(mSpec, &mPreHost, 0, (brk-mSpec));
lastbrk = brk+1;
brk = PL_strpbrk(lastbrk, ":/");
if (brk)
{ {
lastbrk = brk+1; ExtractString(mSpec, &mHost,
brk = PL_strchr(lastbrk, '/'); (lastbrk-mSpec), (brk-lastbrk));
if (brk) // user:pass@host:port/path if (*brk == ':') // user:pass@host:port...
{ {
mPort = ExtractPortFrom(mSpec, (lastbrk-mSpec),(brk-lastbrk)); lastbrk = brk+1;
ExtractString(&mPath, brk = PL_strchr(lastbrk, '/');
(brk-mSpec), len - (brk-mSpec)); if (brk) // user:pass@host:port/path
return NS_OK; {
mPort = ExtractPortFrom(mSpec, (lastbrk-mSpec),(brk-lastbrk));
ExtractString(mSpec, &mPath,
(brk-mSpec), len - (brk-mSpec));
return NS_OK;
}
else // user:pass@host:port
{
mPort = ExtractPortFrom(mSpec, (lastbrk-mSpec),len - (lastbrk-mSpec));
return NS_OK;
}
} }
else // user:pass@host:port else // (*brk == '/') so user:pass@host/path
{ {
mPort = ExtractPortFrom(mSpec, (lastbrk-mSpec),len - (lastbrk-mSpec)); ExtractString(mSpec, &mPath, (brk - mSpec), len - (brk - mSpec));
return NS_OK; return NS_OK;
} }
} }
else // (*brk == '/') so user:pass@host/path else // its user:pass@host so everthing else is just the host
{ {
ExtractString(&mPath, (brk - mSpec), len - (brk - mSpec)); ExtractString(mSpec, &mHost,
(lastbrk-mSpec), len - (lastbrk-mSpec));
return NS_OK; return NS_OK;
} }
}
else // its user:pass@host so everthing else is just the host
{
ExtractString(&mHost,
(lastbrk-mSpec), len - (lastbrk-mSpec));
return NS_OK;
}
break; break;
default: NS_POSTCONDITION(0, "This just can't be!"); default: NS_POSTCONDITION(0, "This just can't be!");
break; break;
}
}
else // Everything else is just the port
{
mPort = ExtractPortFrom(mSpec, lastbrk-mSpec, len - (lastbrk-mSpec));
return NS_OK;
} }
} }
else // Everything else is just the port else // scheme:host...
{ {
mPort = ExtractPortFrom(mSpec, lastbrk-mSpec, len - (lastbrk-mSpec)); ExtractString(mSpec, &mScheme, 0, (brk - mSpec));
return NS_OK; brk = PL_strpbrk(lastbrk, delimiters);
if (brk)
{
switch (*brk)
{
case '/' : // The path, so its scheme:host/path
ExtractString(mSpec, &mHost, (lastbrk-mSpec), (brk-lastbrk));
ExtractString(mSpec, &mPath, (brk - mSpec), len - (brk - mSpec));
return NS_OK;
break;
case '@' : // scheme:user@host...
ExtractString(mSpec, &mPreHost, (lastbrk-mSpec), (brk-lastbrk));
// TODO more here...
break;
case ':' : // scheme:user:pass@host... or scheme:host:port...
/* TODO
if you find @ in the remaining string then // scheme:user:pass@host...
{
}
else // scheme:host:port
{
ExtractString(mSpec, &mHost, (lastbrk-mSpec), (brk-lastbrk));
}
*/
break;
default: NS_POSTCONDITION(0, "This just can't be!");
break;
}
}
else // its just scheme:host
{
ExtractString(mSpec, &mHost, (lastbrk-mSpec), len - (lastbrk-mSpec));
return NS_OK;
}
} }
} }
break; break;
case '@' : case '@' :
//Everything before the @ is the prehost stuff //Everything before the @ is the prehost stuff
ExtractString(&mPreHost, 0, brk-mSpec); ExtractString(mSpec, &mPreHost, 0, brk-mSpec);
lastbrk = brk+1; lastbrk = brk+1;
brk = PL_strpbrk(lastbrk, ":/"); brk = PL_strpbrk(lastbrk, ":/");
if (brk) if (brk)
{ {
ExtractString(&mHost, (lastbrk-mSpec), (brk-lastbrk)); ExtractString(mSpec, &mHost, (lastbrk-mSpec), (brk-lastbrk));
if (*brk == ':') // user@host:port... if (*brk == ':') // user@host:port...
{ {
lastbrk = brk+1; lastbrk = brk+1;
@ -424,7 +464,7 @@ nsStdURL::Parse(void)
if (brk) // user@host:port/path if (brk) // user@host:port/path
{ {
mPort = ExtractPortFrom(mSpec, (lastbrk-mSpec),(brk-lastbrk)); mPort = ExtractPortFrom(mSpec, (lastbrk-mSpec),(brk-lastbrk));
ExtractString(&mPath, (brk-mSpec), len - (brk-mSpec)); ExtractString(mSpec, &mPath, (brk-mSpec), len - (brk-mSpec));
return NS_OK; return NS_OK;
} }
else // user@host:port else // user@host:port
@ -435,24 +475,24 @@ nsStdURL::Parse(void)
} }
else // (*brk == '/') so user@host/path else // (*brk == '/') so user@host/path
{ {
ExtractString(&mPath, (brk - mSpec), len - (brk - mSpec)); ExtractString(mSpec, &mPath, (brk - mSpec), len - (brk - mSpec));
return NS_OK; return NS_OK;
} }
} }
else // its user@host so everything else is just the host else // its user@host so everything else is just the host
{ {
ExtractString(&mHost, (lastbrk-mSpec), (len - (lastbrk-mSpec))); ExtractString(mSpec, &mHost, (lastbrk-mSpec), (len - (lastbrk-mSpec)));
return NS_OK; return NS_OK;
} }
break; break;
default: default:
NS_POSTCONDITION(0, "This just can't be!"); NS_ASSERTION(0, "This just can't be!");
break; break;
} }
} }
else // everything is a host else // everything is a host
{ {
ExtractString(&mHost, 0, len); ExtractString(mSpec, &mHost, 0, len);
} }
return NS_OK; return NS_OK;
} }
@ -460,7 +500,7 @@ nsStdURL::Parse(void)
nsresult nsresult
nsStdURL::ReconstructSpec() nsStdURL::ReconstructSpec()
{ {
PR_FREEIF(mSpec); if (mSpec) nsCRT::free(mSpec);
char portBuffer[10]; char portBuffer[10];
if (-1 != mPort) { if (-1 != mPort) {
@ -494,9 +534,14 @@ nsStdURL::ReconstructSpec()
{ {
finalSpec += mPath; finalSpec += mPath;
} }
//Pathetic hack since nsString returns a new'd string
mSpec = finalSpec.ToNewCString(); char* tempSpec = finalSpec.ToNewCString();
return NS_OK; if(!tempSpec)
return NS_ERROR_OUT_OF_MEMORY;
mSpec = nsCRT::strdup(tempSpec);
delete[] tempSpec;
return (mSpec ? NS_OK : NS_ERROR_OUT_OF_MEMORY);
} }
NS_METHOD NS_METHOD
@ -514,17 +559,17 @@ nsStdURL::Create(nsISupports *aOuter,
} }
nsresult nsresult
nsStdURL::ExtractString(char* *io_Destination, PRUint32 start, PRUint32 length) nsStdURL::ExtractString(char* i_Source, char* *o_Destination, PRUint32 start, PRUint32 length)
{ {
NS_PRECONDITION( (nsnull != mSpec), "Exract called on empty url!"); NS_PRECONDITION( (nsnull != i_Source), "Exract called on empty string!");
if (*io_Destination) if (*o_Destination)
nsCRT::free(*io_Destination); nsCRT::free(*o_Destination);
*io_Destination = new char[length + 1]; *o_Destination = nsnull;
if (!*io_Destination) if (0 == length)
return NS_ERROR_OUT_OF_MEMORY; return NS_OK;
char* startPosition = mSpec + start; char* startPosition = i_Source + start;
PL_strncpyz(*io_Destination, startPosition, length+1); *o_Destination = PL_strndup(startPosition, length);
return NS_OK; return (*o_Destination ? NS_OK : NS_ERROR_OUT_OF_MEMORY);
} }
PRInt32 ExtractPortFrom(char* src, int start, int length) PRInt32 ExtractPortFrom(char* src, int start, int length)
@ -537,7 +582,7 @@ PRInt32 ExtractPortFrom(char* src, int start, int length)
} }
PL_strncpyz(port, src+start, length+1); PL_strncpyz(port, src+start, length+1);
returnValue = atoi(port); returnValue = atoi(port);
delete[] port; delete[] port;
return returnValue; return returnValue;
} }
@ -561,28 +606,316 @@ nsStdURL::DupString(char* *o_Destination, char* i_Source)
NS_IMETHODIMP NS_IMETHODIMP
nsStdURL::SetDirectory(char* i_Directory) nsStdURL::SetDirectory(char* i_Directory)
{ {
return NS_ERROR_NOT_IMPLEMENTED; if (!i_Directory)
//return DupString(&mDirectory, i_Directory); return NS_ERROR_NULL_POINTER;
if (mDirectory)
nsCRT::free(mDirectory);
nsString dir;
if ('/' != *i_Directory)
dir += "/";
dir += i_Directory;
dir.Trim("/",PR_FALSE); // Removes trailing slash if any...
// TODO- Fix this. Hack to create tmp only becuz nsString can't
// give us a PR_Malloc (nsCRT/nsAllocator) string
char* tmp = dir.ToNewCString();
if (!tmp)
return NS_ERROR_OUT_OF_MEMORY;
mDirectory = nsCRT::strdup(tmp);
delete[] tmp;
if (!mDirectory)
return NS_ERROR_OUT_OF_MEMORY;
return ReconstructPath();
} }
NS_IMETHODIMP NS_IMETHODIMP
nsStdURL::SetFileName(char* i_FileName) nsStdURL::SetFileName(char* i_FileName)
{ {
return NS_ERROR_NOT_IMPLEMENTED; nsParsePath pp(this); // Someone mayhave set .. in the name
//return DupString(&mFileName, i_FileName); if (!i_FileName)
return NS_ERROR_NULL_POINTER;
//Cleanout query and ref
CRTFREEIF(mQuery);
CRTFREEIF(mRef);
//If it starts with a / then everything is the path.
if ('/' == *i_FileName)
return SetPath(i_FileName);
if (mFileName) nsCRT::free(mFileName);
nsresult status = DupString(&mFileName, i_FileName);
return (NS_FAILED(status) ? status : ReconstructPath());
} }
NS_IMETHODIMP NS_IMETHODIMP
nsStdURL::SetRef(char* i_Ref) nsStdURL::SetRef(char* i_Ref)
{ {
return NS_ERROR_NOT_IMPLEMENTED; nsresult status;
//return DupString(&mRef, i_Ref); if (i_Ref && (*i_Ref == '#'))
status = DupString(&mRef, i_Ref+1);
else
status = DupString(&mRef, i_Ref);
return (NS_FAILED(status) ? status : ReconstructPath());
} }
NS_IMETHODIMP NS_IMETHODIMP
nsStdURL::SetQuery(char* i_Query) nsStdURL::SetQuery(char* i_Query)
{ {
return NS_ERROR_NOT_IMPLEMENTED; nsresult status;
//return DupString(&mQuery, i_Query); if (i_Query && (*i_Query == '?'))
status = DupString(&mQuery, i_Query+1);
else
status = DupString(&mQuery, i_Query);
return (NS_FAILED(status) ? status : ReconstructPath());
} }
NS_IMETHODIMP
nsStdURL::SetRelativePath(const char* i_Relative)
{
nsresult status = NS_ERROR_FAILURE;
if (!i_Relative)
return NS_ERROR_NULL_POINTER;
// If it has a scheme already then its an absolute URL
nsStdURL temp(i_Relative);
if (temp.mScheme)
{
//we should perhaps clone temp to this
return SetSpec((char*)i_Relative);
}
switch (*i_Relative)
{
case '/': return SetPath((char*) i_Relative);
break;
case '?': return SetQuery((char*) i_Relative);
break;
case '#' : return SetRef((char*) i_Relative);
break;
default: return SetFileName((char*)i_Relative);
break;
}
}
nsresult
nsStdURL::ReconstructPath(void)
{
//Take all the elements of the path and construct it
if (mPath) nsCRT::free(mPath);
nsString path;
if (mDirectory)
{
path = mDirectory;
// if we have anything in the dir besides just the /
if (PL_strlen(mDirectory)>1)
path += '/';
}
if (mFileName)
{
path += mFileName;
}
/* TODO Add parameters as well...
if (mParams)
{
path += ';';
path += mParams;
}
*/
if (mQuery)
{
path += '?';
path += mQuery;
}
if (mRef)
{
path += '#';
path += mRef;
}
//Sad hack since nsString returns new'd string
char* tempPath = path.ToNewCString();
if (!tempPath)
return NS_ERROR_OUT_OF_MEMORY;
ReplaceDotMess(tempPath);
mPath = nsCRT::strdup(tempPath);
delete[] tempPath;
return (mPath ? ReconstructSpec() : NS_ERROR_OUT_OF_MEMORY);
}
/** Extract the elements like directory/filename, query, or ref from
* the path.
*/
nsresult
nsStdURL::ParsePath(void)
{
CRTFREEIF(mDirectory);
CRTFREEIF(mFileName);
CRTFREEIF(mQuery);
CRTFREEIF(mRef);
if (!mPath)
{
DupString(&mDirectory, "/");
return (mDirectory ? ReconstructPath() : NS_ERROR_OUT_OF_MEMORY);
}
int len = PL_strlen(mPath);
if (len == 1)
{
mDirectory = nsCRT::strdup("/");
return (mDirectory ? NS_OK : NS_ERROR_OUT_OF_MEMORY);
}
ReplaceDotMess(mPath);
// if the previous cleanup cleaned up everything then reset it to /
if (PL_strlen(mPath) == 0)
{
DupString(&mDirectory, "/");
return (mDirectory ? ReconstructPath() : NS_ERROR_OUT_OF_MEMORY);
}
// First find the last slash
char* file = PL_strrchr(mPath, '/');
NS_ASSERTION(file, "This can't be! ParsePath called without a /Path");
if (!file) return NS_OK;
// If its not the same as the first slash then extract directory
if (file != mPath)
{
ExtractString(mPath, &mDirectory, 0, (file - mPath));
}
len = PL_strlen(file);
if (len==1)
return NS_OK; // Optimize for www.foo.com/path/
static const char delimiters[] = ";?#"; // for param, query and ref
char* brk = PL_strpbrk(file, delimiters);
if (brk)
{
ExtractString(file, &mFileName, 1 /* skip the leading / */, (brk-file-1));
//Keep pulling out other pieces...
while (brk)
{
char* lastbrk = brk;
brk = PL_strpbrk(lastbrk+1, delimiters);
switch (*lastbrk)
{
case ';' : /*
ExtractString(lastbrk, &mParam, 1, (brk ? (brk-lastbrk-1) : (len - (lastbrk-file) -1)));
*/
break;
case '?' : ExtractString(lastbrk, &mQuery, 1, (brk ? (brk-lastbrk-1) : (len - (lastbrk-file) -1)));
break;
case '#' : ExtractString(lastbrk, &mRef, 1, (brk ? (brk-lastbrk-1) : (len - (lastbrk-file) -1)));
break;
default:
NS_ASSERTION(0, "This just can't be!");
break;
}
}
}
else // Everything in the file is just the filename
{
return DupString(&mFileName, file+1); //+1 to skip the leading slash
}
return NS_OK;
}
NS_METHOD
nsStdURL::SetSpec(char* i_Spec)
{
CRTFREEIF(mSpec);
nsresult status = DupString(&mSpec, i_Spec);
//If spec is being rewritten clean up everything-
CRTFREEIF(mScheme);
CRTFREEIF(mPreHost);
CRTFREEIF(mHost);
mPort = -1;
CRTFREEIF(mPath);
CRTFREEIF(mDirectory);
CRTFREEIF(mFileName);
CRTFREEIF(mQuery);
CRTFREEIF(mRef);
return (NS_FAILED(status) ? status : Parse());
}
NS_METHOD
nsStdURL::SetPath(char* i_Path)
{
if (mPath) nsCRT::free(mPath);
nsresult status = DupString(&mPath, i_Path);
ParsePath();
ReconstructSpec();
return status;
}
void ReplaceDotMess(char* io_Path)
{
// Replace all /./ with a /
/* Stolen from netlib's mkparse.c.
*
* modifies a url of the form /foo/../foo1 -> /foo1
* and /foo/./foo1 -> /foo/foo1
*/
char *fwdPtr = io_Path;
char *urlPtr = io_Path;
for(; *fwdPtr != '\0'; ++fwdPtr)
{
if(*fwdPtr == '/' && *(fwdPtr+1) == '.' && *(fwdPtr+2) == '/')
{
// remove ./
fwdPtr += 1;
}
else if(*fwdPtr == '/' && *(fwdPtr+1) == '.' && *(fwdPtr+2) == '.' &&
(*(fwdPtr+3) == '/' || *(fwdPtr+3) == '\0'))
{
// remove foo/..
// reverse the urlPtr to the previous slash
if(urlPtr != io_Path)
urlPtr--; // we must be going back at least by one
for(;*urlPtr != '/' && urlPtr != io_Path; urlPtr--)
; // null body
// forward the fwd_prt past the ../
fwdPtr += 2;
}
else
{
// copy the url incrementaly
*urlPtr++ = *fwdPtr;
}
}
*urlPtr = '\0'; // terminate the url
}
NS_METHOD
nsStdURL::DirFile(char **o_DirFile)
{
if (!o_DirFile)
return NS_ERROR_NULL_POINTER;
nsString temp;
if (mDirectory)
{
temp = mDirectory;
// if we have anything in the dir besides just the /
if (PL_strlen(mDirectory)>1)
temp += '/';
}
if (mFileName)
{
temp += mFileName;
}
// TODO fix when nsString changes
char* tempDirFile = temp.ToNewCString();
*o_DirFile = nsCRT::strdup(tempDirFile);
delete[] tempDirFile;
if (!*o_DirFile)
return NS_ERROR_OUT_OF_MEMORY;
return NS_OK;
}

Просмотреть файл

@ -21,6 +21,8 @@
#include "nsIURL.h" #include "nsIURL.h"
#include "nsAgg.h" #include "nsAgg.h"
#include "nsCRT.h"
#include "nsString.h" // REMOVE Later!!
#define NS_THIS_STANDARDURL_IMPLEMENTATION_CID \ #define NS_THIS_STANDARDURL_IMPLEMENTATION_CID \
{ /* e3939dc8-29ab-11d3-8cce-0060b0fc14a3 */ \ { /* e3939dc8-29ab-11d3-8cce-0060b0fc14a3 */ \
@ -77,6 +79,9 @@ public:
/* nsIURI Clone (); */ /* nsIURI Clone (); */
NS_IMETHOD Clone(nsIURI **_retval); NS_IMETHOD Clone(nsIURI **_retval);
/* void SetRelativePath (in string i_RelativePath); */
NS_IMETHOD SetRelativePath(const char *i_RelativePath);
//////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////
// nsIURL methods: // nsIURL methods:
@ -96,12 +101,19 @@ public:
NS_IMETHOD GetRef(char * *aRef); NS_IMETHOD GetRef(char * *aRef);
NS_IMETHOD SetRef(char * aRef); NS_IMETHOD SetRef(char * aRef);
/* void DirFile (out string o_DirFile); */
NS_IMETHOD DirFile(char **o_DirFile);
/* todo move this to protected later */
nsresult ParsePath(void);
protected: protected:
nsresult Parse(void); nsresult Parse(void);
nsresult ReconstructPath(void);
nsresult ReconstructSpec(void); nsresult ReconstructSpec(void);
// Some handy functions
nsresult DupString(char* *o_Destination, char* i_Source); nsresult DupString(char* *o_Destination, char* i_Source);
nsresult ExtractString(char* *io_Destination, PRUint32 start, PRUint32 length); nsresult ExtractString(char* i_Source, char* *o_Destination, PRUint32 start, PRUint32 length);
protected: protected:
char* mScheme; char* mScheme;
@ -177,17 +189,10 @@ nsStdURL::GetQuery(char* *o_Query)
return DupString(o_Query, mQuery); return DupString(o_Query, mQuery);
} }
inline NS_METHOD
nsStdURL::SetSpec(char* i_Spec)
{
nsresult status = DupString(&mSpec, i_Spec);
if (NS_FAILED(status)) return status;
return Parse();
}
inline NS_METHOD inline NS_METHOD
nsStdURL::SetScheme(char* i_Scheme) nsStdURL::SetScheme(char* i_Scheme)
{ {
if (mScheme) nsCRT::free(mScheme);
nsresult status = DupString(&mScheme, i_Scheme); nsresult status = DupString(&mScheme, i_Scheme);
ReconstructSpec(); ReconstructSpec();
return status; return status;
@ -196,6 +201,7 @@ nsStdURL::SetScheme(char* i_Scheme)
inline NS_METHOD inline NS_METHOD
nsStdURL::SetPreHost(char* i_PreHost) nsStdURL::SetPreHost(char* i_PreHost)
{ {
if (mPreHost) nsCRT::free(mPreHost);
nsresult status = DupString(&mPreHost, i_PreHost); nsresult status = DupString(&mPreHost, i_PreHost);
ReconstructSpec(); ReconstructSpec();
return status; return status;
@ -204,19 +210,12 @@ nsStdURL::SetPreHost(char* i_PreHost)
inline NS_METHOD inline NS_METHOD
nsStdURL::SetHost(char* i_Host) nsStdURL::SetHost(char* i_Host)
{ {
if (mHost) nsCRT::free(mHost);
nsresult status = DupString(&mHost, i_Host); nsresult status = DupString(&mHost, i_Host);
ReconstructSpec(); ReconstructSpec();
return status; return status;
} }
inline NS_METHOD
nsStdURL::SetPath(char* i_Path)
{
nsresult status = DupString(&mPath, i_Path);
ReconstructSpec();
return status;
}
inline NS_METHOD inline NS_METHOD
nsStdURL::GetPort(PRInt32 *aPort) nsStdURL::GetPort(PRInt32 *aPort)
{ {

Просмотреть файл

@ -24,7 +24,7 @@
//#include "nsFileTransportService.h" //#include "nsFileTransportService.h"
#include "nsSocketTransportService.h" #include "nsSocketTransportService.h"
#include "nscore.h" #include "nscore.h"
#include "nsStandardUrl.h" #include "nsStdURL.h"
#include "nsSimpleURI.h" #include "nsSimpleURI.h"
#include "nsDnsService.h" #include "nsDnsService.h"
#include "nsLoadGroup.h" #include "nsLoadGroup.h"
@ -70,7 +70,7 @@ NSGetFactory(nsISupports* aServMgr,
rv = NS_NewGenericFactory(&fact, nsDNSService::Create); rv = NS_NewGenericFactory(&fact, nsDNSService::Create);
} }
else if (aClass.Equals(kStandardURLCID)) { else if (aClass.Equals(kStandardURLCID)) {
rv = NS_NewGenericFactory(&fact, nsStandardURL::Create); rv = NS_NewGenericFactory(&fact, nsStdURL::Create);
} }
else if (aClass.Equals(kSimpleURICID)) { else if (aClass.Equals(kSimpleURICID)) {
rv = NS_NewGenericFactory(&fact, nsSimpleURI::Create); rv = NS_NewGenericFactory(&fact, nsSimpleURI::Create);

Просмотреть файл

@ -108,15 +108,17 @@ nsAboutProtocolHandler::NewURI(const char *aSpec, nsIURI *aBaseURI,
nsIURI* url; nsIURI* url;
if (aBaseURI) { if (aBaseURI) {
rv = aBaseURI->Clone(&url); rv = aBaseURI->Clone(&url);
if (NS_FAILED(rv)) return rv;
rv = url->SetRelativePath(aSpec);
} }
else { else {
rv = nsComponentManager::CreateInstance(kSimpleURICID, nsnull, rv = nsComponentManager::CreateInstance(kSimpleURICID, nsnull,
nsIURI::GetIID(), nsIURI::GetIID(),
(void**)&url); (void**)&url);
} if (NS_FAILED(rv)) return rv;
if (NS_FAILED(rv)) return rv; rv = url->SetSpec((char*)aSpec);
rv = url->SetSpec((char*)aSpec); }
if (NS_FAILED(rv)) { if (NS_FAILED(rv)) {
NS_RELEASE(url); NS_RELEASE(url);
return rv; return rv;

Просмотреть файл

@ -126,15 +126,17 @@ nsFileProtocolHandler::NewURI(const char *aSpec, nsIURI *aBaseURI,
nsIURI* url; nsIURI* url;
if (aBaseURI) { if (aBaseURI) {
rv = aBaseURI->Clone(&url); rv = aBaseURI->Clone(&url);
if (NS_FAILED(rv)) return rv;
rv = url->SetRelativePath(aSpec);
} }
else { else {
rv = nsComponentManager::CreateInstance(kStandardURLCID, nsnull, rv = nsComponentManager::CreateInstance(kStandardURLCID, nsnull,
nsCOMTypeInfo<nsIURI>::GetIID(), nsCOMTypeInfo<nsIURI>::GetIID(),
(void**)&url); (void**)&url);
if (NS_FAILED(rv)) return rv;
rv = url->SetSpec((char*)aSpec);
} }
if (NS_FAILED(rv)) return rv;
rv = url->SetSpec((char*)aSpec);
if (NS_FAILED(rv)) { if (NS_FAILED(rv)) {
NS_RELEASE(url); NS_RELEASE(url);
return rv; return rv;

Просмотреть файл

@ -98,15 +98,16 @@ nsFtpProtocolHandler::NewURI(const char *aSpec, nsIURI *aBaseURI,
nsIURI* url; nsIURI* url;
if (aBaseURI) { if (aBaseURI) {
rv = aBaseURI->Clone(&url); rv = aBaseURI->Clone(&url);
if (NS_FAILED(rv)) return rv;
rv = url->SetRelativePath(aSpec);
} }
else { else {
rv = nsComponentManager::CreateInstance(kStandardURLCID, nsnull, rv = nsComponentManager::CreateInstance(kStandardURLCID, nsnull,
nsCOMTypeInfo<nsIURI>::GetIID(), nsCOMTypeInfo<nsIURI>::GetIID(),
(void**)&url); (void**)&url);
if (NS_FAILED(rv)) return rv;
rv = url->SetSpec((char*)aSpec);
} }
if (NS_FAILED(rv)) return rv;
rv = url->SetSpec((char*)aSpec);
if (NS_FAILED(rv)) { if (NS_FAILED(rv)) {
NS_RELEASE(url); NS_RELEASE(url);
return rv; return rv;

Просмотреть файл

@ -225,12 +225,17 @@ nsHTTPHandler::NewURI(const char *aSpec, nsIURI *aBaseURI,
nsIURI* url; nsIURI* url;
if (aBaseURI) if (aBaseURI)
{
rv = aBaseURI->Clone(&url); rv = aBaseURI->Clone(&url);
if (NS_FAILED(rv)) return rv;
rv = url->SetRelativePath(aSpec);
}
else else
{
rv = nsComponentManager::CreateInstance(kStandardUrlCID, nsnull, nsCOMTypeInfo<nsIURI>::GetIID(), (void**)&url); rv = nsComponentManager::CreateInstance(kStandardUrlCID, nsnull, nsCOMTypeInfo<nsIURI>::GetIID(), (void**)&url);
if (NS_FAILED(rv)) return rv; if (NS_FAILED(rv)) return rv;
rv = url->SetSpec((char*)aSpec);
rv = url->SetSpec((char*)aSpec); }
nsIURI* realUrl = nsnull; nsIURI* realUrl = nsnull;

Просмотреть файл

@ -132,15 +132,12 @@ nsHTTPRequest::Build()
rv = m_pURI->GetPath(&name); rv = m_pURI->GetPath(&name);
lineBuffer.Append(name); lineBuffer.Append(name);
nsCRT::free(name); nsCRT::free(name);
// Append the Query string if any...
name = nsnull; name = nsnull;
rv = m_pURI->GetQuery(&name);
if (name && *name) { //Trim off the # portion if any...
lineBuffer.Append("?"); int refLocation = lineBuffer.RFind("#");
lineBuffer.Append(name); if (-1 != refLocation)
} lineBuffer.Truncate(refLocation);
nsCRT::free(name);
lineBuffer.Append(" HTTP/1.0"CRLF); lineBuffer.Append(" HTTP/1.0"CRLF);

Просмотреть файл

@ -125,15 +125,17 @@ nsResourceProtocolHandler::NewURI(const char *aSpec, nsIURI *aBaseURI,
nsIURI* url; nsIURI* url;
if (aBaseURI) { if (aBaseURI) {
rv = aBaseURI->Clone(&url); rv = aBaseURI->Clone(&url);
if (NS_FAILED(rv)) return rv;
rv = url->SetRelativePath(aSpec);
} }
else { else {
rv = nsComponentManager::CreateInstance(kStandardURLCID, nsnull, rv = nsComponentManager::CreateInstance(kStandardURLCID, nsnull,
nsCOMTypeInfo<nsIURI>::GetIID(), nsCOMTypeInfo<nsIURI>::GetIID(),
(void**)&url); (void**)&url);
if (NS_FAILED(rv)) return rv;
rv = url->SetSpec((char*)aSpec);
} }
if (NS_FAILED(rv)) return rv;
rv = url->SetSpec((char*)aSpec);
if (NS_FAILED(rv)) { if (NS_FAILED(rv)) {
NS_RELEASE(url); NS_RELEASE(url);
return rv; return rv;

Просмотреть файл

@ -29,6 +29,7 @@
#include "nsIURL.h" #include "nsIURL.h"
#include "nsCOMPtr.h" #include "nsCOMPtr.h"
#include "iostream.h" #include "iostream.h"
#include "nsXPIDLString.h"
// Define CIDs... // Define CIDs...
static NS_DEFINE_CID(kIOServiceCID, NS_IOSERVICE_CID); static NS_DEFINE_CID(kIOServiceCID, NS_IOSERVICE_CID);
@ -90,112 +91,286 @@ int writeout(const char* i_pURL, PRBool bUseStd =PR_TRUE)
return -1; return -1;
} }
/* construct a url and print out its five elements separated by commas */
nsresult testURL(const char* i_pURL, PRBool bUseStd=PR_TRUE) nsresult testURL(const char* i_pURL, PRBool bUseStd=PR_TRUE)
{ {
const int tests = 9;
if (i_pURL)
return writeout(i_pURL, bUseStd);
/* /*
If you add a test case then make sure you also add the expected If you add a test case then make sure you also add the expected
result in the resultset as well. result in the resultset as well.
*/ */
if (i_pURL) const int tests = 9;
const char* url[tests] =
{ {
writeout(i_pURL, bUseStd); "http://username:password@hostname.com:80/pathname/./more/stuff/../path",
} "username@host:8080/path",
else "http://gagan/",
"host:port/netlib", //port should now be 0
"", //empty string
"mailbox:///foo", // No host specified path should be /foo
"user:pass@hostname.edu:80/pathname", //this is always user:pass and not http:user
"http://username:password@hostname:80/pathname",
"resource:/pathname"
};
const char* resultset[tests] =
{ {
const char* url[tests] = "http,username:password,hostname.com,80,/pathname/more/path",
{ ",username,host,8080,/path",
"http://username:password@hostname.com:80/pathname/./more/stuff/../path", "http,,gagan,-1,/",
"username@host:8080/path", ",,host,0,/netlib",
"http://gagan/", ",,,-1,",
"host:port/netlib", //port should now be 0 "mailbox,,,-1,/foo",
"", //empty string ",user:pass,hostname.edu,80,/pathname",
"mailbox:///foo", // No host specified path should be /foo "http,username:password,hostname,80,/pathname",
"user:pass@hostname.edu:80/pathname", //this is always user:pass and not http:user "resource,,,-1,/pathname"
"http://username:password@hostname:80/pathname", };
"resource:/pathname"
};
const char* resultset[tests] = // These tests will fail to create a URI from NS_NewURI calls...
{ // because of a missing scheme: in front. This set assumes
"http,username:password,hostname.com,80,/pathname/more/path", // an only working http handler is available. When we switch on mail these
",username,host,8080,/path", // results will change!
"http,,gagan,-1,/", PRBool failWithURI[tests] =
",,host,0,/netlib", {
",,,-1,", PR_FALSE,
"mailbox,,,-1,/foo", PR_TRUE,
",user:pass,hostname.edu,80,/pathname", PR_FALSE,
"http,username:password,hostname,80,/pathname", PR_TRUE,
"resource,,,-1,/pathname" PR_TRUE,
}; PR_TRUE,
PR_TRUE,
// These tests will fail to create a URI from NS_NewURI calls... PR_FALSE,
// because of a missing scheme: in front. This set assumes PR_FALSE
// an only working the handler is available. };
PRBool failWithURI[tests] = nsresult stat;
{ for (int i = 0; i< tests; ++i)
PR_FALSE, {
PR_TRUE, cout << "--------------------" << endl;
PR_FALSE, if (!bUseStd)
PR_TRUE, cout << "Should" << (failWithURI[i] ? " not " : " ")
PR_TRUE, << "create URL" << endl;
PR_TRUE, stat = writeout(url[i], bUseStd);
PR_TRUE, if (NS_FAILED(stat))
PR_FALSE, return stat;
PR_FALSE if (bUseStd || !failWithURI[i])
}; cout << "Expect " << resultset[i] << endl << endl;
nsresult stat;
for (int i = 0; i< tests; ++i)
{
cout << "--------------------" << endl;
if (!bUseStd)
cout << "Should" << (failWithURI[i] ? " not " : " ")
<< "create URL" << endl;
stat = writeout(url[i], bUseStd);
if (NS_FAILED(stat))
return stat;
if (bUseStd || !failWithURI[i])
cout << "Expect " << resultset[i] << endl << endl;
}
} }
return 0; return 0;
} }
int makeAbsTest(const char* i_BaseURI, const char* relativePortion)
{
if (!i_BaseURI)
return -1;
nsIURI* baseURL;
nsresult status = nsComponentManager::CreateInstance(kStdURLCID, nsnull,
nsCOMTypeInfo<nsIURI>::GetIID(), (void**)&baseURL);
if (NS_FAILED(status))
{
cout << "CreateInstance failed" << endl;
return status;
}
status = baseURL->SetSpec((char*)i_BaseURI);
if (NS_FAILED(status)) return status;
nsCOMPtr<nsIURI> url;
nsresult rv = baseURL->Clone(getter_AddRefs(url));
if (NS_FAILED(rv) || !url) return -1;
rv = url->SetRelativePath(relativePortion);
if (NS_FAILED(rv)) return -1;
nsXPIDLCString temp;
baseURL->GetSpec(getter_Copies(temp));
cout << "Analyzing " << temp << endl;
cout << "With " << relativePortion << endl;
url->GetSpec(getter_Copies(temp));
cout << "Got " << temp << endl;
return 0;
}
int doMakeAbsTest(const char* i_URL = 0, const char* i_relativePortion=0)
{
if (i_URL && i_relativePortion)
{
return makeAbsTest(i_URL, i_relativePortion);
}
// Run standard tests. These tests are based on the ones described in
// rfc1808
/* Section 5.1. Normal Examples
g:h = <URL:g:h>
g = <URL:http://a/b/c/g>
./g = <URL:http://a/b/c/g>
g/ = <URL:http://a/b/c/g/>
/g = <URL:http://a/g>
//g = <URL:http://g>
?y = <URL:http://a/b/c/d;p?y>
g?y = <URL:http://a/b/c/g?y>
g?y/./x = <URL:http://a/b/c/g?y/./x>
#s = <URL:http://a/b/c/d;p?q#s>
g#s = <URL:http://a/b/c/g#s>
g#s/./x = <URL:http://a/b/c/g#s/./x>
g?y#s = <URL:http://a/b/c/g?y#s>
;x = <URL:http://a/b/c/d;x>
g;x = <URL:http://a/b/c/g;x>
g;x?y#s = <URL:http://a/b/c/g;x?y#s>
. = <URL:http://a/b/c/>
./ = <URL:http://a/b/c/>
.. = <URL:http://a/b/>
../ = <URL:http://a/b/>
../g = <URL:http://a/b/g>
../.. = <URL:http://a/>
../../ = <URL:http://a/>
../../g = <URL:http://a/g>
*/
const int tests = 24;
const char baseURL[] = "http://a/b/c/d;p?q#f";
const char* rel[tests] =
{
"g:h",
"g",
"./g",
"g/",
"/g",
"//g",
"?y",
"g?y",
"g?y/./x",
"#s",
"g#s",
"g#s/./x",
"g?y#s",
";x",
"g;x",
"g;x?y#s",
".",
"./",
"..",
"../",
"../g",
"../..",
"../../",
"../../g"
};
const char* results[tests] =
{
"g:h",
"http://a/b/c/g",
"http://a/b/c/g",
"http://a/b/c/g/",
"http://a/g",
"http://g",
"http://a/b/c/d;p?y",
"http://a/b/c/g?y",
"http://a/b/c/g?y/./x",
"http://a/b/c/d;p?q#s",
"http://a/b/c/g#s",
"http://a/b/c/g#s/./x",
"http://a/b/c/g?y#s",
"http://a/b/c/d;x",
"http://a/b/c/g;x",
"http://a/b/c/g;x?y#s",
"http://a/b/c/",
"http://a/b/c/",
"http://a/b/",
"http://a/b/",
"http://a/b/g",
"http://a/",
"http://a/",
"http://a/g"
};
for (int i = 0 ; i<tests ; ++i)
{
makeAbsTest(baseURL, rel[i]);
cout << "Expect " << results[i] << endl << endl;
}
return 0;
}
nsresult NS_AutoregisterComponents() nsresult NS_AutoregisterComponents()
{ {
nsresult rv = nsComponentManager::AutoRegister(nsIComponentManager::NS_Startup, NULL /* default */); nsresult rv = nsComponentManager::AutoRegister(nsIComponentManager::NS_Startup, NULL /* default */);
return rv; return rv;
} }
void printusage(void)
{
printf("urltest [-std] [-all] <URL> [-abs <relative>]\n");
printf("\n");
printf(" -std : Generate results using nsStdURL. \n");
printf(" <URL> : The string representing the URL. \n");
printf(" -all : Run all standard tests. Ignores <URL> then. \n");
printf(" -abs : Make an absolute URL from the base (<URI>) and the\n");
printf(" relative path specified. Can be used with -all. Implies -std.\n");
}
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
nsresult result = NS_OK; nsresult result = NS_OK;
if (argc < 2) { if (argc < 2) {
printf("urltest [-std] [<URL> | -all]\n"); printusage();
return 0; return 0;
} }
result = NS_AutoregisterComponents(); result = NS_AutoregisterComponents();
if (NS_FAILED(result)) return result; if (NS_FAILED(result)) return result;
cout << "------------------" << endl << endl; // end of all messages from register components...
PRBool bStdTest= PR_FALSE; PRBool bStdTest= PR_FALSE;
PRBool bTestAll= PR_FALSE; PRBool bTestAll= PR_FALSE;
PRBool bMakeAbs= PR_FALSE;
char* relativePath = 0;
char* url = 0;
for (int i=1; i<argc; i++) { for (int i=1; i<argc; i++) {
if (PL_strcasecmp(argv[i], "-std") == 0) if (PL_strcasecmp(argv[i], "-std") == 0)
{ {
bStdTest = PR_TRUE; bStdTest = PR_TRUE;
continue; }
} else if (PL_strcasecmp(argv[i], "-all") == 0)
if (PL_strcasecmp(argv[i], "-all") == 0)
{ {
bTestAll = PR_TRUE; bTestAll = PR_TRUE;
continue; }
} else if (PL_strcasecmp(argv[i], "-abs") == 0)
{
if (i+1 >= argc)
{
printusage();
return 0;
}
relativePath = argv[i+1];
bMakeAbs = PR_TRUE;
i++;
}
else
{
url = argv[i];
}
} }
return bTestAll ? testURL(0,bStdTest) : testURL(argv[argc-1],bStdTest); if (bMakeAbs)
{
return bTestAll ? doMakeAbsTest() : doMakeAbsTest(url, relativePath);
}
else
{
return bTestAll ? testURL(0, bStdTest) : testURL(url, bStdTest);
}
} }