Back to index

lightning-sunbird  0.9+nobinonly
urltest.cpp
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
00002 /* ***** BEGIN LICENSE BLOCK *****
00003  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00004  *
00005  * The contents of this file are subject to the Mozilla Public License Version
00006  * 1.1 (the "License"); you may not use this file except in compliance with
00007  * the License. You may obtain a copy of the License at
00008  * http://www.mozilla.org/MPL/
00009  *
00010  * Software distributed under the License is distributed on an "AS IS" basis,
00011  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00012  * for the specific language governing rights and limitations under the
00013  * License.
00014  *
00015  * The Original Code is mozilla.org code.
00016  *
00017  * The Initial Developer of the Original Code is
00018  * Netscape Communications Corporation.
00019  * Portions created by the Initial Developer are Copyright (C) 1998
00020  * the Initial Developer. All Rights Reserved.
00021  *
00022  * Contributor(s):
00023  *   Pierre Phaneuf <pp@ludusdesign.com>
00024  *
00025  * Alternatively, the contents of this file may be used under the terms of
00026  * either the GNU General Public License Version 2 or later (the "GPL"), or
00027  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00028  * in which case the provisions of the GPL or the LGPL are applicable instead
00029  * of those above. If you wish to allow use of your version of this file only
00030  * under the terms of either the GPL or the LGPL, and not to allow others to
00031  * use your version of this file under the terms of the MPL, indicate your
00032  * decision by deleting the provisions above and replace them with the notice
00033  * and other provisions required by the GPL or the LGPL. If you do not delete
00034  * the provisions above, a recipient may use your version of this file under
00035  * the terms of any one of the MPL, the GPL or the LGPL.
00036  *
00037  * ***** END LICENSE BLOCK ***** */
00038 
00039 /*
00040     A test file to check default URL parsing.
00041     -Gagan Saksena 03/25/99
00042 */
00043 
00044 #include <stdio.h>
00045 
00046 #include "TestCommon.h"
00047 #include "plstr.h"
00048 #include "nsIServiceManager.h"
00049 #include "nsIIOService.h"
00050 #include "nsIURL.h"
00051 #include "nsCOMPtr.h"
00052 #include "nsXPIDLString.h"
00053 #include "nsString.h"
00054 #include "nsReadableUtils.h"
00055 #include "nsCRT.h"
00056 #include "nsNetCID.h"
00057 #include "nsIComponentRegistrar.h"
00058 
00059 // Define CIDs...
00060 static NS_DEFINE_CID(kIOServiceCID,              NS_IOSERVICE_CID);
00061 static NS_DEFINE_CID(kStdURLCID,                 NS_STANDARDURL_CID);
00062 
00063 char* gFileIO = 0;
00064 
00065 enum {
00066     URL_FACTORY_DEFAULT,
00067     URL_FACTORY_STDURL
00068 };
00069 
00070 nsresult writeoutto(const char* i_pURL, char** o_Result, PRInt32 urlFactory = URL_FACTORY_DEFAULT)
00071 {
00072     if (!o_Result || !i_pURL)
00073         return NS_ERROR_FAILURE;
00074     *o_Result = 0;
00075     nsCOMPtr<nsIURI> pURL;
00076     nsresult result = NS_OK;
00077 
00078     switch (urlFactory) {
00079         case URL_FACTORY_STDURL: {
00080             nsIURI* url;
00081             result = CallCreateInstance(kStdURLCID, &url);
00082             if (NS_FAILED(result))
00083             {
00084                 printf("CreateInstance failed\n");
00085                 return NS_ERROR_FAILURE;
00086             }
00087             pURL = url;
00088             pURL->SetSpec(nsDependentCString(i_pURL));
00089             break;
00090         }
00091         case URL_FACTORY_DEFAULT: {
00092             nsCOMPtr<nsIIOService> pService = 
00093                      do_GetService(kIOServiceCID, &result);
00094             if (NS_FAILED(result)) 
00095             {
00096                 printf("Service failed!\n");
00097                 return NS_ERROR_FAILURE;
00098             }   
00099             result = pService->NewURI(nsDependentCString(i_pURL), nsnull, nsnull, getter_AddRefs(pURL));
00100         }
00101     }
00102 
00103     nsCString output;
00104     if (NS_SUCCEEDED(result))
00105     {
00106         nsCOMPtr<nsIURL> tURL = do_QueryInterface(pURL);
00107         nsCAutoString temp;
00108         PRInt32 port;
00109         nsresult rv;
00110 
00111 #define RESULT() NS_SUCCEEDED(rv) ? temp.get() : ""
00112 
00113         rv = tURL->GetScheme(temp);
00114         output += RESULT();
00115         output += ',';
00116         rv = tURL->GetUsername(temp);
00117         output += RESULT();
00118         output += ',';
00119         rv = tURL->GetPassword(temp);
00120         output += RESULT();
00121         output += ',';
00122         rv = tURL->GetHost(temp);
00123         output += RESULT();
00124         output += ',';
00125         rv = tURL->GetPort(&port);
00126         output.AppendInt(port);
00127         output += ',';
00128         rv = tURL->GetDirectory(temp);
00129         output += RESULT();
00130         output += ',';
00131         rv = tURL->GetFileBaseName(temp);
00132         output += RESULT();
00133         output += ',';
00134         rv = tURL->GetFileExtension(temp);
00135         output += RESULT();
00136         output += ',';
00137         rv = tURL->GetParam(temp);
00138         output += RESULT();
00139         output += ',';
00140         rv = tURL->GetQuery(temp);
00141         output += RESULT();
00142         output += ',';
00143         rv = tURL->GetRef(temp);
00144         output += RESULT();
00145         output += ',';
00146         rv = tURL->GetSpec(temp);
00147         output += RESULT();
00148         *o_Result = ToNewCString(output);
00149     } else {
00150         output = "Can not create URL";
00151         *o_Result = ToNewCString(output);
00152     }
00153     return NS_OK;
00154 }
00155 
00156 nsresult writeout(const char* i_pURL, PRInt32 urlFactory = URL_FACTORY_DEFAULT)
00157 {
00158     char* temp = 0;
00159     if (!i_pURL) return NS_ERROR_FAILURE;
00160     int rv = writeoutto(i_pURL, &temp, urlFactory);
00161     printf("%s\n%s\n", i_pURL, temp);
00162     delete[] temp;
00163     return rv;
00164 }
00165 
00166 /* construct a url and print out its elements separated by commas and
00167    the whole spec */
00168 nsresult testURL(const char* i_pURL, PRInt32 urlFactory = URL_FACTORY_DEFAULT)
00169 {
00170 
00171     if (i_pURL)
00172         return writeout(i_pURL, urlFactory);
00173 
00174     if (!gFileIO)
00175         return NS_ERROR_FAILURE;
00176 
00177     FILE *testfile = fopen(gFileIO, "rt");
00178     if (!testfile) 
00179     {
00180         fprintf(stderr, "Cannot open testfile: %s\n", gFileIO);
00181         return NS_ERROR_FAILURE;
00182     }
00183 
00184     char temp[512];
00185     int count=0;
00186     int failed=0;
00187     char* prevResult = nsnull;
00188     char* tempurl = nsnull;
00189 
00190     while (fgets(temp,512,testfile))
00191     {
00192         if (*temp == '#' || !*temp)
00193             continue;
00194 
00195         if (0 == count%3)
00196         {
00197             if (prevResult) delete[] prevResult;
00198             printf("Testing:  %s\n", temp);
00199             writeoutto(temp, &prevResult, urlFactory);
00200         }
00201         else if (1 == count%3) {
00202             if (tempurl) delete[] tempurl;
00203             tempurl = nsCRT::strdup(temp);
00204         } else { 
00205             if (!prevResult)
00206                 printf("no results to compare to!\n");
00207             else 
00208             {
00209                 PRInt32 res;
00210                 printf("Result:   %s\n", prevResult);
00211                 if (urlFactory != URL_FACTORY_DEFAULT) {
00212                     printf("Expected: %s\n", tempurl);
00213                     res = PL_strcmp(tempurl, prevResult);
00214                 } else {
00215                     printf("Expected: %s\n", temp);
00216                     res = PL_strcmp(temp, prevResult);
00217                 }
00218 
00219                 if (res == 0)
00220                     printf("\tPASSED\n\n");
00221                 else 
00222                 {
00223                     printf("\tFAILED\n\n");
00224                     failed++;
00225                 }
00226             }
00227         }
00228         count++;
00229     }
00230     if (failed>0) {
00231         printf("%d tests FAILED out of %d\n", failed, count/3);
00232         return NS_ERROR_FAILURE;
00233     } else {
00234         printf("All %d tests PASSED.\n", count/3);
00235         return NS_OK;
00236     }
00237 }
00238 
00239 nsresult makeAbsTest(const char* i_BaseURI, const char* relativePortion,
00240                      const char* expectedResult)
00241 {
00242     if (!i_BaseURI)
00243         return NS_ERROR_FAILURE;
00244 
00245     // build up the base URL
00246     nsresult status;
00247     nsCOMPtr<nsIURI> baseURL = do_CreateInstance(kStdURLCID, &status);
00248     if (NS_FAILED(status))
00249     {
00250         printf("CreateInstance failed\n");
00251         return status;
00252     }
00253     status = baseURL->SetSpec(nsDependentCString(i_BaseURI));
00254     if (NS_FAILED(status)) return status;
00255 
00256 
00257     // get the new spec
00258     nsCAutoString newURL;
00259     status = baseURL->Resolve(nsDependentCString(relativePortion), newURL);
00260     if (NS_FAILED(status)) return status;
00261 
00262     nsCAutoString temp;
00263     baseURL->GetSpec(temp);
00264 
00265     printf("Analyzing %s\n", temp.get());
00266     printf("With      %s\n", relativePortion);
00267 
00268     printf("Got       %s\n", newURL.get());
00269     if (expectedResult) {
00270         printf("Expect    %s\n", expectedResult);
00271         int res = PL_strcmp(newURL.get(), expectedResult);
00272         if (res == 0) {
00273             printf("\tPASSED\n\n");
00274             return NS_OK;
00275         } else {
00276             printf("\tFAILED\n\n");
00277             return NS_ERROR_FAILURE;
00278         }
00279     }
00280     return NS_OK;
00281 }
00282 
00283 int doMakeAbsTest(const char* i_URL = 0, const char* i_relativePortion=0)
00284 {
00285     if (i_URL && i_relativePortion)
00286     {
00287         return makeAbsTest(i_URL, i_relativePortion, nsnull);
00288     }
00289 
00290     // Run standard tests. These tests are based on the ones described in 
00291     // rfc2396 with the exception of the handling of ?y which is wrong as
00292     // notified by on of the RFC authors.
00293 
00294     /* Section C.1.  Normal Examples
00295 
00296       g:h        = <URL:g:h>
00297       g          = <URL:http://a/b/c/g>
00298       ./g        = <URL:http://a/b/c/g>
00299       g/         = <URL:http://a/b/c/g/>
00300       /g         = <URL:http://a/g>
00301       //g        = <URL:http://g>
00302       ?y         = <URL:http://a/b/c/d;p?y>
00303       g?y        = <URL:http://a/b/c/g?y>
00304       g?y/./x    = <URL:http://a/b/c/g?y/./x>
00305       #s         = <URL:http://a/b/c/d;p?q#s>
00306       g#s        = <URL:http://a/b/c/g#s>
00307       g#s/./x    = <URL:http://a/b/c/g#s/./x>
00308       g?y#s      = <URL:http://a/b/c/g?y#s>
00309       ;x         = <URL:http://a/b/c/;x>
00310       g;x        = <URL:http://a/b/c/g;x>
00311       g;x?y#s    = <URL:http://a/b/c/g;x?y#s>
00312       .          = <URL:http://a/b/c/>
00313       ./         = <URL:http://a/b/c/>
00314       ..         = <URL:http://a/b/>
00315       ../        = <URL:http://a/b/>
00316       ../g       = <URL:http://a/b/g>
00317       ../..      = <URL:http://a/>
00318       ../../     = <URL:http://a/>
00319       ../../g    = <URL:http://a/g>
00320     */
00321 
00322     struct test {
00323         const char* baseURL;
00324         const char* relativeURL;
00325         const char* expectedResult;
00326     };
00327 
00328     test tests[] = {
00329         // Tests from rfc2396, section C.1 with the exception of the
00330         // handling of ?y
00331         { "http://a/b/c/d;p?q#f",     "g:h",         "g:h" },
00332         { "http://a/b/c/d;p?q#f",     "g",           "http://a/b/c/g" },
00333         { "http://a/b/c/d;p?q#f",     "./g",         "http://a/b/c/g" },
00334         { "http://a/b/c/d;p?q#f",     "g/",          "http://a/b/c/g/" },
00335         { "http://a/b/c/d;p?q#f",     "/g",          "http://a/g" },
00336         { "http://a/b/c/d;p?q#f",     "//g",         "http://g" },
00337         { "http://a/b/c/d;p?q#f",     "?y",          "http://a/b/c/d;p?y" },
00338         { "http://a/b/c/d;p?q#f",     "g?y",         "http://a/b/c/g?y" },
00339         { "http://a/b/c/d;p?q#f",     "g?y/./x",     "http://a/b/c/g?y/./x" },
00340         { "http://a/b/c/d;p?q#f",     "#s",          "http://a/b/c/d;p?q#s" },
00341         { "http://a/b/c/d;p?q#f",     "g#s",         "http://a/b/c/g#s" },
00342         { "http://a/b/c/d;p?q#f",     "g#s/./x",     "http://a/b/c/g#s/./x" },
00343         { "http://a/b/c/d;p?q#f",     "g?y#s",       "http://a/b/c/g?y#s" },
00344         { "http://a/b/c/d;p?q#f",     ";x",          "http://a/b/c/;x" },
00345         { "http://a/b/c/d;p?q#f",     "g;x",         "http://a/b/c/g;x" },
00346         { "http://a/b/c/d;p?q#f",     "g;x?y#s",     "http://a/b/c/g;x?y#s" },
00347         { "http://a/b/c/d;p?q#f",     ".",           "http://a/b/c/" },
00348         { "http://a/b/c/d;p?q#f",     "./",          "http://a/b/c/" },
00349         { "http://a/b/c/d;p?q#f",     "..",          "http://a/b/" },
00350         { "http://a/b/c/d;p?q#f",     "../",         "http://a/b/" },
00351         { "http://a/b/c/d;p?q#f",     "../g",        "http://a/b/g" },
00352         { "http://a/b/c/d;p?q#f",     "../..",       "http://a/" },
00353         { "http://a/b/c/d;p?q#f",     "../../",      "http://a/" },
00354         { "http://a/b/c/d;p?q#f",     "../../g",     "http://a/g" },
00355 
00356         // Our additional tests...
00357         { "http://a/b/c/d;p?q#f",     "#my::anchor", "http://a/b/c/d;p?q#my::anchor" },
00358         { "http://a/b/c/d;p?q#f",     "get?baseRef=viewcert.jpg", "http://a/b/c/get?baseRef=viewcert.jpg" },
00359 
00360         // Make sure relative query's work right even if the query
00361         // string contains absolute urls or other junk.
00362         { "http://a/b/c/d;p?q#f",     "?http://foo",        "http://a/b/c/d;p?http://foo" },
00363         { "http://a/b/c/d;p?q#f",     "g?http://foo",       "http://a/b/c/g?http://foo" },
00364         {"http://a/b/c/d;p?q#f",      "g/h?http://foo",     "http://a/b/c/g/h?http://foo" },
00365         { "http://a/b/c/d;p?q#f",     "g/h/../H?http://foo","http://a/b/c/g/H?http://foo" },
00366         { "http://a/b/c/d;p?q#f",     "g/h/../H?http://foo?baz", "http://a/b/c/g/H?http://foo?baz" },
00367         { "http://a/b/c/d;p?q#f",     "g/h/../H?http://foo;baz", "http://a/b/c/g/H?http://foo;baz" },
00368         { "http://a/b/c/d;p?q#f",     "g/h/../H?http://foo#bar", "http://a/b/c/g/H?http://foo#bar" },
00369         { "http://a/b/c/d;p?q#f",     "g/h/../H;baz?http://foo", "http://a/b/c/g/H;baz?http://foo" },
00370         { "http://a/b/c/d;p?q#f",     "g/h/../H;baz?http://foo#bar", "http://a/b/c/g/H;baz?http://foo#bar" },
00371         { "http://a/b/c/d;p?q#f",     "g/h/../H;baz?C:\\temp", "http://a/b/c/g/H;baz?C:\\temp" },
00372         { "http://a/b/c/d;p?q#f",     "", "http://a/b/c/d;p?q" },
00373         { "http://a/b/c/d;p?q#f",     "#", "http://a/b/c/d;p?q#" },
00374         { "http://a/b/c;p/d;p?q#f",   "../g;p" , "http://a/b/g;p" },
00375 
00376     };
00377 
00378     const int numTests = sizeof(tests) / sizeof(tests[0]);
00379     int failed = 0;
00380     nsresult rv;
00381     for (int i = 0 ; i<numTests ; ++i)
00382     {
00383         rv = makeAbsTest(tests[i].baseURL, tests[i].relativeURL,
00384                          tests[i].expectedResult);
00385         if (NS_FAILED(rv))
00386             failed++;
00387     }
00388     if (failed>0) {
00389         printf("%d tests FAILED out of %d\n", failed, numTests);
00390         return NS_ERROR_FAILURE;
00391     } else {
00392         printf("All %d tests PASSED.\n", numTests);
00393         return NS_OK;
00394     }
00395 }
00396 
00397 void printusage(void)
00398 {
00399     printf("urltest [-std] [-file <filename>] <URL> "
00400            " [-abs <relative>]\n\n"
00401            "\t-std  : Generate results using nsStdURL.\n"
00402            "\t-file : Read URLs from file.\n"
00403            "\t-abs  : Make an absolute URL from the base (<URL>) and the\n"
00404            "\t\trelative path specified. If -abs is given without\n"
00405            "\t\ta base URI standard RFC 2396 relative URL tests\n"
00406            "\t\tare performed. Implies -std.\n"
00407            "\t<URL> : The string representing the URL.\n");
00408 }
00409 
00410 int main(int argc, char **argv)
00411 {
00412     if (test_common_init(&argc, &argv) != 0)
00413         return -1;
00414 
00415     int rv = -1;
00416 
00417     if (argc < 2) {
00418         printusage();
00419         return NS_OK;
00420     }
00421     {
00422         nsCOMPtr<nsIServiceManager> servMan;
00423         NS_InitXPCOM2(getter_AddRefs(servMan), nsnull, nsnull);
00424         nsCOMPtr<nsIComponentRegistrar> registrar = do_QueryInterface(servMan);
00425         NS_ASSERTION(registrar, "Null nsIComponentRegistrar");
00426         if (registrar)
00427             registrar->AutoRegister(nsnull);
00428 
00429         // end of all messages from register components...
00430         printf("------------------\n\n");
00431 
00432         PRInt32 urlFactory = URL_FACTORY_DEFAULT;
00433         PRBool bMakeAbs= PR_FALSE;
00434         char* relativePath = 0;
00435         char* url = 0;
00436         for (int i=1; i<argc; i++) {
00437             if (PL_strcasecmp(argv[i], "-std") == 0)
00438             {
00439                 urlFactory = URL_FACTORY_STDURL;
00440                 if (i+1 >= argc)
00441                 {
00442                     printusage();
00443                     return NS_OK;
00444                 }
00445             }
00446             else if (PL_strcasecmp(argv[i], "-abs") == 0)
00447             {
00448                 if (!gFileIO)
00449                 {
00450                     relativePath = argv[i+1];
00451                     i++;
00452                 }
00453                 bMakeAbs = PR_TRUE;
00454             }
00455             else if (PL_strcasecmp(argv[i], "-file") == 0)
00456             {
00457                 if (i+1 >= argc)
00458                 {
00459                     printusage();
00460                     return NS_OK;
00461                 }
00462                 gFileIO = argv[i+1];
00463                 i++;
00464             }
00465             else
00466             {
00467                 url = argv[i];
00468             }
00469         }
00470         PRTime startTime = PR_Now();
00471         if (bMakeAbs)
00472         {
00473             rv = (url && relativePath)
00474                ? doMakeAbsTest(url, relativePath)
00475                : doMakeAbsTest();
00476         }
00477         else
00478         {
00479             rv = gFileIO ? testURL(0, urlFactory) : testURL(url, urlFactory);
00480         }
00481         if (gFileIO)
00482         {
00483             PRTime endTime = PR_Now();
00484             printf("Elapsed time: %d micros.\n", (PRInt32)
00485                 (endTime - startTime));
00486         }
00487     } // this scopes the nsCOMPtrs
00488     // no nsCOMPtrs are allowed to be alive when you call NS_ShutdownXPCOM
00489     rv = NS_ShutdownXPCOM(nsnull);
00490     return rv;
00491 }