michael@0: /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: /* michael@0: A test file to check default URL parsing. michael@0: -Gagan Saksena 03/25/99 michael@0: */ michael@0: michael@0: #include michael@0: michael@0: #include "TestCommon.h" michael@0: #include "plstr.h" michael@0: #include "nsIServiceManager.h" michael@0: #include "nsIIOService.h" michael@0: #include "nsIURL.h" michael@0: #include "nsCOMPtr.h" michael@0: #include "nsStringAPI.h" michael@0: #include "nsNetCID.h" michael@0: #include "nsIComponentRegistrar.h" michael@0: #include "nsComponentManagerUtils.h" michael@0: #include "nsServiceManagerUtils.h" michael@0: #include "nsXPCOM.h" michael@0: #include "prprf.h" michael@0: michael@0: // Define CIDs... michael@0: static NS_DEFINE_CID(kIOServiceCID, NS_IOSERVICE_CID); michael@0: static NS_DEFINE_CID(kStdURLCID, NS_STANDARDURL_CID); michael@0: michael@0: char* gFileIO = 0; michael@0: michael@0: enum { michael@0: URL_FACTORY_DEFAULT, michael@0: URL_FACTORY_STDURL michael@0: }; michael@0: michael@0: nsresult writeoutto(const char* i_pURL, char** o_Result, int32_t urlFactory = URL_FACTORY_DEFAULT) michael@0: { michael@0: if (!o_Result || !i_pURL) michael@0: return NS_ERROR_FAILURE; michael@0: *o_Result = 0; michael@0: nsCOMPtr pURL; michael@0: nsresult result = NS_OK; michael@0: michael@0: switch (urlFactory) { michael@0: case URL_FACTORY_STDURL: { michael@0: nsIURI* url; michael@0: result = CallCreateInstance(kStdURLCID, &url); michael@0: if (NS_FAILED(result)) michael@0: { michael@0: printf("CreateInstance failed\n"); michael@0: return NS_ERROR_FAILURE; michael@0: } michael@0: pURL = url; michael@0: pURL->SetSpec(nsDependentCString(i_pURL)); michael@0: break; michael@0: } michael@0: case URL_FACTORY_DEFAULT: { michael@0: nsCOMPtr pService = michael@0: do_GetService(kIOServiceCID, &result); michael@0: if (NS_FAILED(result)) michael@0: { michael@0: printf("Service failed!\n"); michael@0: return NS_ERROR_FAILURE; michael@0: } michael@0: result = pService->NewURI(nsDependentCString(i_pURL), nullptr, nullptr, getter_AddRefs(pURL)); michael@0: } michael@0: } michael@0: michael@0: nsCString output; michael@0: if (NS_SUCCEEDED(result)) michael@0: { michael@0: nsCOMPtr tURL = do_QueryInterface(pURL); michael@0: nsAutoCString temp; michael@0: int32_t port; michael@0: nsresult rv; michael@0: michael@0: #define RESULT() NS_SUCCEEDED(rv) ? temp.get() : "" michael@0: michael@0: rv = tURL->GetScheme(temp); michael@0: output += RESULT(); michael@0: output += ','; michael@0: rv = tURL->GetUsername(temp); michael@0: output += RESULT(); michael@0: output += ','; michael@0: rv = tURL->GetPassword(temp); michael@0: output += RESULT(); michael@0: output += ','; michael@0: rv = tURL->GetHost(temp); michael@0: output += RESULT(); michael@0: output += ','; michael@0: rv = tURL->GetPort(&port); michael@0: char portbuffer[40]; michael@0: PR_snprintf(portbuffer, sizeof(portbuffer), "%d", port); michael@0: output.Append(portbuffer); michael@0: output += ','; michael@0: rv = tURL->GetDirectory(temp); michael@0: output += RESULT(); michael@0: output += ','; michael@0: rv = tURL->GetFileBaseName(temp); michael@0: output += RESULT(); michael@0: output += ','; michael@0: rv = tURL->GetFileExtension(temp); michael@0: output += RESULT(); michael@0: output += ','; michael@0: // removed with https://bugzilla.mozilla.org/show_bug.cgi?id=665706 michael@0: // rv = tURL->GetParam(temp); michael@0: // output += RESULT(); michael@0: output += ','; michael@0: rv = tURL->GetQuery(temp); michael@0: output += RESULT(); michael@0: output += ','; michael@0: rv = tURL->GetRef(temp); michael@0: output += RESULT(); michael@0: output += ','; michael@0: rv = tURL->GetSpec(temp); michael@0: output += RESULT(); michael@0: *o_Result = ToNewCString(output); michael@0: } else { michael@0: output = "Can not create URL"; michael@0: *o_Result = ToNewCString(output); michael@0: } michael@0: return NS_OK; michael@0: } michael@0: michael@0: nsresult writeout(const char* i_pURL, int32_t urlFactory = URL_FACTORY_DEFAULT) michael@0: { michael@0: if (!i_pURL) return NS_ERROR_FAILURE; michael@0: nsCString temp; michael@0: nsresult rv = writeoutto(i_pURL, getter_Copies(temp), urlFactory); michael@0: printf("%s\n%s\n", i_pURL, temp.get()); michael@0: return rv; michael@0: } michael@0: michael@0: /* construct a url and print out its elements separated by commas and michael@0: the whole spec */ michael@0: nsresult testURL(const char* i_pURL, int32_t urlFactory = URL_FACTORY_DEFAULT) michael@0: { michael@0: michael@0: if (i_pURL) michael@0: return writeout(i_pURL, urlFactory); michael@0: michael@0: if (!gFileIO) michael@0: return NS_ERROR_FAILURE; michael@0: michael@0: FILE *testfile = fopen(gFileIO, "rt"); michael@0: if (!testfile) michael@0: { michael@0: fprintf(stderr, "Cannot open testfile: %s\n", gFileIO); michael@0: return NS_ERROR_FAILURE; michael@0: } michael@0: michael@0: char temp[512]; michael@0: int count=0; michael@0: int failed=0; michael@0: nsCString prevResult; michael@0: nsCString tempurl; michael@0: michael@0: while (fgets(temp,512,testfile)) michael@0: { michael@0: if (*temp == '#' || !*temp) michael@0: continue; michael@0: michael@0: if (0 == count%3) michael@0: { michael@0: printf("Testing: %s\n", temp); michael@0: writeoutto(temp, getter_Copies(prevResult), urlFactory); michael@0: } michael@0: else if (1 == count%3) { michael@0: tempurl.Assign(temp); michael@0: } else { michael@0: if (prevResult.IsEmpty()) michael@0: printf("no results to compare to!\n"); michael@0: else michael@0: { michael@0: int32_t res; michael@0: printf("Result: %s\n", prevResult.get()); michael@0: if (urlFactory != URL_FACTORY_DEFAULT) { michael@0: printf("Expected: %s\n", tempurl.get()); michael@0: res = PL_strcmp(tempurl.get(), prevResult.get()); michael@0: } else { michael@0: printf("Expected: %s\n", temp); michael@0: res = PL_strcmp(temp, prevResult.get()); michael@0: } michael@0: michael@0: if (res == 0) michael@0: printf("\tPASSED\n\n"); michael@0: else michael@0: { michael@0: printf("\tFAILED\n\n"); michael@0: failed++; michael@0: } michael@0: } michael@0: } michael@0: count++; michael@0: } michael@0: if (failed>0) { michael@0: printf("%d tests FAILED out of %d\n", failed, count/3); michael@0: return NS_ERROR_FAILURE; michael@0: } else { michael@0: printf("All %d tests PASSED.\n", count/3); michael@0: return NS_OK; michael@0: } michael@0: } michael@0: michael@0: nsresult makeAbsTest(const char* i_BaseURI, const char* relativePortion, michael@0: const char* expectedResult) michael@0: { michael@0: if (!i_BaseURI) michael@0: return NS_ERROR_FAILURE; michael@0: michael@0: // build up the base URL michael@0: nsresult status; michael@0: nsCOMPtr baseURL = do_CreateInstance(kStdURLCID, &status); michael@0: if (NS_FAILED(status)) michael@0: { michael@0: printf("CreateInstance failed\n"); michael@0: return status; michael@0: } michael@0: status = baseURL->SetSpec(nsDependentCString(i_BaseURI)); michael@0: if (NS_FAILED(status)) return status; michael@0: michael@0: michael@0: // get the new spec michael@0: nsAutoCString newURL; michael@0: status = baseURL->Resolve(nsDependentCString(relativePortion), newURL); michael@0: if (NS_FAILED(status)) return status; michael@0: michael@0: nsAutoCString temp; michael@0: baseURL->GetSpec(temp); michael@0: michael@0: printf("Analyzing %s\n", temp.get()); michael@0: printf("With %s\n", relativePortion); michael@0: michael@0: printf("Got %s\n", newURL.get()); michael@0: if (expectedResult) { michael@0: printf("Expect %s\n", expectedResult); michael@0: int res = PL_strcmp(newURL.get(), expectedResult); michael@0: if (res == 0) { michael@0: printf("\tPASSED\n\n"); michael@0: return NS_OK; michael@0: } else { michael@0: printf("\tFAILED\n\n"); michael@0: return NS_ERROR_FAILURE; michael@0: } michael@0: } michael@0: return NS_OK; michael@0: } michael@0: michael@0: nsresult doMakeAbsTest(const char* i_URL = 0, const char* i_relativePortion=0) michael@0: { michael@0: if (i_URL && i_relativePortion) michael@0: { michael@0: return makeAbsTest(i_URL, i_relativePortion, nullptr); michael@0: } michael@0: michael@0: // Run standard tests. These tests are based on the ones described in michael@0: // rfc2396 with the exception of the handling of ?y which is wrong as michael@0: // notified by on of the RFC authors. michael@0: michael@0: /* Section C.1. Normal Examples michael@0: michael@0: g:h = michael@0: g = michael@0: ./g = michael@0: g/ = michael@0: /g = michael@0: //g = michael@0: ?y = michael@0: g?y = michael@0: g?y/./x = michael@0: #s = michael@0: g#s = michael@0: g#s/./x = michael@0: g?y#s = michael@0: ;x = michael@0: g;x = michael@0: g;x?y#s = michael@0: . = michael@0: ./ = michael@0: .. = michael@0: ../ = michael@0: ../g = michael@0: ../.. = michael@0: ../../ = michael@0: ../../g = michael@0: */ michael@0: michael@0: struct test { michael@0: const char* baseURL; michael@0: const char* relativeURL; michael@0: const char* expectedResult; michael@0: }; michael@0: michael@0: test tests[] = { michael@0: // Tests from rfc2396, section C.1 with the exception of the michael@0: // handling of ?y michael@0: { "http://a/b/c/d;p?q#f", "g:h", "g:h" }, michael@0: { "http://a/b/c/d;p?q#f", "g", "http://a/b/c/g" }, michael@0: { "http://a/b/c/d;p?q#f", "./g", "http://a/b/c/g" }, michael@0: { "http://a/b/c/d;p?q#f", "g/", "http://a/b/c/g/" }, michael@0: { "http://a/b/c/d;p?q#f", "/g", "http://a/g" }, michael@0: { "http://a/b/c/d;p?q#f", "//g", "http://g" }, michael@0: { "http://a/b/c/d;p?q#f", "?y", "http://a/b/c/d;p?y" }, michael@0: { "http://a/b/c/d;p?q#f", "g?y", "http://a/b/c/g?y" }, michael@0: { "http://a/b/c/d;p?q#f", "g?y/./x", "http://a/b/c/g?y/./x" }, michael@0: { "http://a/b/c/d;p?q#f", "#s", "http://a/b/c/d;p?q#s" }, michael@0: { "http://a/b/c/d;p?q#f", "g#s", "http://a/b/c/g#s" }, michael@0: { "http://a/b/c/d;p?q#f", "g#s/./x", "http://a/b/c/g#s/./x" }, michael@0: { "http://a/b/c/d;p?q#f", "g?y#s", "http://a/b/c/g?y#s" }, michael@0: { "http://a/b/c/d;p?q#f", ";x", "http://a/b/c/;x" }, michael@0: { "http://a/b/c/d;p?q#f", "g;x", "http://a/b/c/g;x" }, michael@0: { "http://a/b/c/d;p?q#f", "g;x?y#s", "http://a/b/c/g;x?y#s" }, michael@0: { "http://a/b/c/d;p?q#f", ".", "http://a/b/c/" }, michael@0: { "http://a/b/c/d;p?q#f", "./", "http://a/b/c/" }, michael@0: { "http://a/b/c/d;p?q#f", "..", "http://a/b/" }, michael@0: { "http://a/b/c/d;p?q#f", "../", "http://a/b/" }, michael@0: { "http://a/b/c/d;p?q#f", "../g", "http://a/b/g" }, michael@0: { "http://a/b/c/d;p?q#f", "../..", "http://a/" }, michael@0: { "http://a/b/c/d;p?q#f", "../../", "http://a/" }, michael@0: { "http://a/b/c/d;p?q#f", "../../g", "http://a/g" }, michael@0: michael@0: // Our additional tests... michael@0: { "http://a/b/c/d;p?q#f", "#my::anchor", "http://a/b/c/d;p?q#my::anchor" }, michael@0: { "http://a/b/c/d;p?q#f", "get?baseRef=viewcert.jpg", "http://a/b/c/get?baseRef=viewcert.jpg" }, michael@0: michael@0: // Make sure relative query's work right even if the query michael@0: // string contains absolute urls or other junk. michael@0: { "http://a/b/c/d;p?q#f", "?http://foo", "http://a/b/c/d;p?http://foo" }, michael@0: { "http://a/b/c/d;p?q#f", "g?http://foo", "http://a/b/c/g?http://foo" }, michael@0: {"http://a/b/c/d;p?q#f", "g/h?http://foo", "http://a/b/c/g/h?http://foo" }, michael@0: { "http://a/b/c/d;p?q#f", "g/h/../H?http://foo","http://a/b/c/g/H?http://foo" }, michael@0: { "http://a/b/c/d;p?q#f", "g/h/../H?http://foo?baz", "http://a/b/c/g/H?http://foo?baz" }, michael@0: { "http://a/b/c/d;p?q#f", "g/h/../H?http://foo;baz", "http://a/b/c/g/H?http://foo;baz" }, michael@0: { "http://a/b/c/d;p?q#f", "g/h/../H?http://foo#bar", "http://a/b/c/g/H?http://foo#bar" }, michael@0: { "http://a/b/c/d;p?q#f", "g/h/../H;baz?http://foo", "http://a/b/c/g/H;baz?http://foo" }, michael@0: { "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" }, michael@0: { "http://a/b/c/d;p?q#f", "g/h/../H;baz?C:\\temp", "http://a/b/c/g/H;baz?C:\\temp" }, michael@0: { "http://a/b/c/d;p?q#f", "", "http://a/b/c/d;p?q" }, michael@0: { "http://a/b/c/d;p?q#f", "#", "http://a/b/c/d;p?q#" }, michael@0: { "http://a/b/c;p/d;p?q#f", "../g;p" , "http://a/b/g;p" }, michael@0: michael@0: }; michael@0: michael@0: const int numTests = sizeof(tests) / sizeof(tests[0]); michael@0: int failed = 0; michael@0: nsresult rv; michael@0: for (int i = 0 ; i0) { michael@0: printf("%d tests FAILED out of %d\n", failed, numTests); michael@0: return NS_ERROR_FAILURE; michael@0: } else { michael@0: printf("All %d tests PASSED.\n", numTests); michael@0: return NS_OK; michael@0: } michael@0: } michael@0: michael@0: void printusage(void) michael@0: { michael@0: printf("urltest [-std] [-file ] " michael@0: " [-abs ]\n\n" michael@0: "\t-std : Generate results using nsStdURL.\n" michael@0: "\t-file : Read URLs from file.\n" michael@0: "\t-abs : Make an absolute URL from the base () and the\n" michael@0: "\t\trelative path specified. If -abs is given without\n" michael@0: "\t\ta base URI standard RFC 2396 relative URL tests\n" michael@0: "\t\tare performed. Implies -std.\n" michael@0: "\t : The string representing the URL.\n"); michael@0: } michael@0: michael@0: int main(int argc, char **argv) michael@0: { michael@0: if (test_common_init(&argc, &argv) != 0) michael@0: return -1; michael@0: michael@0: if (argc < 2) { michael@0: printusage(); michael@0: return 0; michael@0: } michael@0: { michael@0: nsCOMPtr servMan; michael@0: NS_InitXPCOM2(getter_AddRefs(servMan), nullptr, nullptr); michael@0: michael@0: // end of all messages from register components... michael@0: printf("------------------\n\n"); michael@0: michael@0: int32_t urlFactory = URL_FACTORY_DEFAULT; michael@0: bool bMakeAbs= false; michael@0: char* relativePath = 0; michael@0: char* url = 0; michael@0: for (int i=1; i= argc) michael@0: { michael@0: printusage(); michael@0: return 0; michael@0: } michael@0: } michael@0: else if (PL_strcasecmp(argv[i], "-abs") == 0) michael@0: { michael@0: if (!gFileIO) michael@0: { michael@0: relativePath = argv[i+1]; michael@0: i++; michael@0: } michael@0: bMakeAbs = true; michael@0: } michael@0: else if (PL_strcasecmp(argv[i], "-file") == 0) michael@0: { michael@0: if (i+1 >= argc) michael@0: { michael@0: printusage(); michael@0: return 0; michael@0: } michael@0: gFileIO = argv[i+1]; michael@0: i++; michael@0: } michael@0: else michael@0: { michael@0: url = argv[i]; michael@0: } michael@0: } michael@0: PRTime startTime = PR_Now(); michael@0: if (bMakeAbs) michael@0: { michael@0: if (url && relativePath) { michael@0: doMakeAbsTest(url, relativePath); michael@0: } else { michael@0: doMakeAbsTest(); michael@0: } michael@0: } michael@0: else michael@0: { michael@0: if (gFileIO) { michael@0: testURL(0, urlFactory); michael@0: } else { michael@0: testURL(url, urlFactory); michael@0: } michael@0: } michael@0: if (gFileIO) michael@0: { michael@0: PRTime endTime = PR_Now(); michael@0: printf("Elapsed time: %d micros.\n", (int32_t) michael@0: (endTime - startTime)); michael@0: } michael@0: } // this scopes the nsCOMPtrs michael@0: // no nsCOMPtrs are allowed to be alive when you call NS_ShutdownXPCOM michael@0: return NS_FAILED(NS_ShutdownXPCOM(nullptr)) ? 1 : 0; michael@0: }