Bug 1146304 - Touch slider bar or tap forward button, the video got stuck 1s then...
[gecko.git] / netwerk / test / TestProtocols.cpp
blob79a3ee1dd1fb141a4f1e109a47dea042c0eb634f
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=2 sw=2 et cindent: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 /*
8 The TestProtocols tests the basic protocols architecture and can
9 be used to test individual protocols as well. If this grows too
10 big then we should split it to individual protocols.
12 -Gagan Saksena 04/29/99
15 #include "TestCommon.h"
16 #include <algorithm>
18 #define FORCE_PR_LOG
19 #include <stdio.h>
20 #ifdef WIN32
21 #include <windows.h>
22 #endif
23 #ifdef XP_UNIX
24 #include <unistd.h>
25 #endif
26 #include "nspr.h"
27 #include "nscore.h"
28 #include "nsCOMPtr.h"
29 #include "nsIIOService.h"
30 #include "nsIServiceManager.h"
31 #include "nsIStreamListener.h"
32 #include "nsIInputStream.h"
33 #include "nsIInputStream.h"
34 #include "nsCRT.h"
35 #include "nsIChannel.h"
36 #include "nsIResumableChannel.h"
37 #include "nsIURL.h"
38 #include "nsIHttpChannel.h"
39 #include "nsIHttpChannelInternal.h"
40 #include "nsIHttpHeaderVisitor.h"
41 #include "nsIChannelEventSink.h"
42 #include "nsIAsyncVerifyRedirectCallback.h"
43 #include "nsIInterfaceRequestor.h"
44 #include "nsIInterfaceRequestorUtils.h"
45 #include "nsIDNSService.h"
46 #include "nsIAuthPrompt.h"
47 #include "nsIPrefService.h"
48 #include "nsIPrefBranch.h"
49 #include "nsIPropertyBag2.h"
50 #include "nsIWritablePropertyBag2.h"
51 #include "nsITimedChannel.h"
52 #include "nsChannelProperties.h"
53 #include "mozilla/Attributes.h"
54 #include "mozilla/unused.h"
56 #include "nsISimpleEnumerator.h"
57 #include "nsStringAPI.h"
58 #include "nsNetUtil.h"
59 #include "prlog.h"
61 using namespace mozilla;
63 namespace TestProtocols {
65 #if defined(PR_LOGGING)
67 // set NSPR_LOG_MODULES=Test:5
69 static PRLogModuleInfo *gTestLog = nullptr;
70 #endif
71 #define LOG(args) PR_LOG(gTestLog, PR_LOG_DEBUG, args)
73 static NS_DEFINE_CID(kIOServiceCID, NS_IOSERVICE_CID);
75 //static PRTime gElapsedTime; // enable when we time it...
76 static int gKeepRunning = 0;
77 static bool gVerbose = false;
78 static bool gAskUserForInput = false;
79 static bool gResume = false;
80 static uint64_t gStartAt = 0;
82 static const char* gEntityID;
84 //-----------------------------------------------------------------------------
85 // Set proxy preferences for testing
86 //-----------------------------------------------------------------------------
88 static nsresult
89 SetHttpProxy(const char *proxy)
91 const char *colon = strchr(proxy, ':');
92 if (!colon)
94 NS_WARNING("invalid proxy token; use host:port");
95 return NS_ERROR_UNEXPECTED;
97 int port = atoi(colon + 1);
98 if (port == 0)
100 NS_WARNING("invalid proxy port; must be an integer");
101 return NS_ERROR_UNEXPECTED;
103 nsAutoCString proxyHost;
104 proxyHost = Substring(proxy, colon);
106 nsCOMPtr<nsIPrefBranch> prefs = do_GetService(NS_PREFSERVICE_CONTRACTID);
107 if (prefs)
109 prefs->SetCharPref("network.proxy.http", proxyHost.get());
110 prefs->SetIntPref("network.proxy.http_port", port);
111 prefs->SetIntPref("network.proxy.type", 1); // manual proxy config
113 LOG(("connecting via proxy=%s:%d\n", proxyHost.get(), port));
114 return NS_OK;
117 static nsresult
118 SetPACFile(const char* pacURL)
120 nsCOMPtr<nsIPrefBranch> prefs = do_GetService(NS_PREFSERVICE_CONTRACTID);
121 if (prefs)
123 prefs->SetCharPref("network.proxy.autoconfig_url", pacURL);
124 prefs->SetIntPref("network.proxy.type", 2); // PAC file
126 LOG(("connecting using PAC file %s\n", pacURL));
127 return NS_OK;
130 //-----------------------------------------------------------------------------
131 // Timing information
132 //-----------------------------------------------------------------------------
134 void PrintTimingInformation(nsITimedChannel* channel) {
135 #define PRINT_VALUE(property) \
137 PRTime value; \
138 channel->Get##property(&value); \
139 if (value) { \
140 PRExplodedTime exploded; \
141 PR_ExplodeTime(value, PR_LocalTimeParameters, &exploded); \
142 char buf[256]; \
143 PR_FormatTime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S", &exploded); \
144 LOG((" " #property ":\t%s (%i usec)", buf, exploded.tm_usec)); \
145 } else { \
146 LOG((" " #property ":\t0")); \
149 LOG(("Timing data:"));
150 PRINT_VALUE(ChannelCreationTime)
151 PRINT_VALUE(AsyncOpenTime)
152 PRINT_VALUE(DomainLookupStartTime)
153 PRINT_VALUE(DomainLookupEndTime)
154 PRINT_VALUE(ConnectStartTime)
155 PRINT_VALUE(ConnectEndTime)
156 PRINT_VALUE(RequestStartTime)
157 PRINT_VALUE(ResponseStartTime)
158 PRINT_VALUE(ResponseEndTime)
159 PRINT_VALUE(CacheReadStartTime)
160 PRINT_VALUE(CacheReadEndTime)
163 //-----------------------------------------------------------------------------
164 // HeaderVisitor
165 //-----------------------------------------------------------------------------
167 class HeaderVisitor : public nsIHttpHeaderVisitor
169 virtual ~HeaderVisitor() {}
170 public:
171 NS_DECL_ISUPPORTS
172 NS_DECL_NSIHTTPHEADERVISITOR
174 HeaderVisitor() { }
176 NS_IMPL_ISUPPORTS(HeaderVisitor, nsIHttpHeaderVisitor)
178 NS_IMETHODIMP
179 HeaderVisitor::VisitHeader(const nsACString &header, const nsACString &value)
181 LOG((" %s: %s\n",
182 PromiseFlatCString(header).get(),
183 PromiseFlatCString(value).get()));
184 return NS_OK;
187 //-----------------------------------------------------------------------------
188 // URLLoadInfo
189 //-----------------------------------------------------------------------------
191 class URLLoadInfo : public nsISupports
193 virtual ~URLLoadInfo();
195 public:
197 URLLoadInfo(const char* aUrl);
199 // ISupports interface...
200 NS_DECL_THREADSAFE_ISUPPORTS
202 const char* Name() { return mURLString.get(); }
203 int64_t mBytesRead;
204 PRTime mTotalTime;
205 PRTime mConnectTime;
206 nsCString mURLString;
209 URLLoadInfo::URLLoadInfo(const char *aUrl) : mURLString(aUrl)
211 mBytesRead = 0;
212 mConnectTime = mTotalTime = PR_Now();
215 URLLoadInfo::~URLLoadInfo()
220 NS_IMPL_ISUPPORTS0(URLLoadInfo)
222 //-----------------------------------------------------------------------------
223 // TestChannelEventSink
224 //-----------------------------------------------------------------------------
226 class TestChannelEventSink : public nsIChannelEventSink
228 virtual ~TestChannelEventSink();
230 public:
231 NS_DECL_ISUPPORTS
232 NS_DECL_NSICHANNELEVENTSINK
234 TestChannelEventSink();
237 TestChannelEventSink::TestChannelEventSink()
241 TestChannelEventSink::~TestChannelEventSink()
246 NS_IMPL_ISUPPORTS(TestChannelEventSink, nsIChannelEventSink)
248 NS_IMETHODIMP
249 TestChannelEventSink::AsyncOnChannelRedirect(nsIChannel *channel,
250 nsIChannel *newChannel,
251 uint32_t flags,
252 nsIAsyncVerifyRedirectCallback *callback)
254 LOG(("\n+++ TestChannelEventSink::OnChannelRedirect (with flags %x) +++\n",
255 flags));
256 callback->OnRedirectVerifyCallback(NS_OK);
257 return NS_OK;
260 //-----------------------------------------------------------------------------
261 // TestAuthPrompt
262 //-----------------------------------------------------------------------------
264 class TestAuthPrompt : public nsIAuthPrompt
266 virtual ~TestAuthPrompt();
268 public:
269 NS_DECL_ISUPPORTS
270 NS_DECL_NSIAUTHPROMPT
272 TestAuthPrompt();
275 NS_IMPL_ISUPPORTS(TestAuthPrompt, nsIAuthPrompt)
277 TestAuthPrompt::TestAuthPrompt()
281 TestAuthPrompt::~TestAuthPrompt()
285 NS_IMETHODIMP
286 TestAuthPrompt::Prompt(const char16_t *dialogTitle,
287 const char16_t *text,
288 const char16_t *passwordRealm,
289 uint32_t savePassword,
290 const char16_t *defaultText,
291 char16_t **result,
292 bool *_retval)
294 *_retval = false;
295 return NS_ERROR_NOT_IMPLEMENTED;
298 NS_IMETHODIMP
299 TestAuthPrompt::PromptUsernameAndPassword(const char16_t *dialogTitle,
300 const char16_t *dialogText,
301 const char16_t *passwordRealm,
302 uint32_t savePassword,
303 char16_t **user,
304 char16_t **pwd,
305 bool *_retval)
307 NS_ConvertUTF16toUTF8 text(passwordRealm);
308 printf("* --------------------------------------------------------------------------- *\n");
309 printf("* Authentication Required [%s]\n", text.get());
310 printf("* --------------------------------------------------------------------------- *\n");
312 char buf[256];
313 int n;
315 printf("Enter username: ");
316 unused << fgets(buf, sizeof(buf), stdin);
317 n = strlen(buf);
318 buf[n-1] = '\0'; // trim trailing newline
319 *user = NS_StringCloneData(NS_ConvertUTF8toUTF16(buf));
321 const char *p;
322 #if defined(XP_UNIX) && !defined(ANDROID)
323 p = getpass("Enter password: ");
324 #else
325 printf("Enter password: ");
326 fgets(buf, sizeof(buf), stdin);
327 n = strlen(buf);
328 buf[n-1] = '\0'; // trim trailing newline
329 p = buf;
330 #endif
331 *pwd = NS_StringCloneData(NS_ConvertUTF8toUTF16(p));
333 // zap buf
334 memset(buf, 0, sizeof(buf));
336 *_retval = true;
337 return NS_OK;
340 NS_IMETHODIMP
341 TestAuthPrompt::PromptPassword(const char16_t *dialogTitle,
342 const char16_t *text,
343 const char16_t *passwordRealm,
344 uint32_t savePassword,
345 char16_t **pwd,
346 bool *_retval)
348 *_retval = false;
349 return NS_ERROR_NOT_IMPLEMENTED;
352 //-----------------------------------------------------------------------------
353 // InputTestConsumer
354 //-----------------------------------------------------------------------------
356 class InputTestConsumer : public nsIStreamListener
358 virtual ~InputTestConsumer();
360 public:
362 InputTestConsumer();
364 NS_DECL_ISUPPORTS
365 NS_DECL_NSIREQUESTOBSERVER
366 NS_DECL_NSISTREAMLISTENER
369 InputTestConsumer::InputTestConsumer()
373 InputTestConsumer::~InputTestConsumer()
377 NS_IMPL_ISUPPORTS(InputTestConsumer, nsIStreamListener, nsIRequestObserver)
379 NS_IMETHODIMP
380 InputTestConsumer::OnStartRequest(nsIRequest *request, nsISupports* context)
382 LOG(("InputTestConsumer::OnStartRequest\n"));
384 URLLoadInfo* info = (URLLoadInfo*)context;
385 if (info)
386 info->mConnectTime = PR_Now() - info->mConnectTime;
388 if (gVerbose) {
389 LOG(("\nStarted loading: %s\n", info ? info->Name() : "UNKNOWN URL"));
392 nsAutoCString value;
394 nsCOMPtr<nsIChannel> channel = do_QueryInterface(request);
395 if (channel) {
396 nsresult status;
397 channel->GetStatus(&status);
398 LOG(("Channel Status: %08x\n", status));
399 if (NS_SUCCEEDED(status)) {
400 LOG(("Channel Info:\n"));
402 channel->GetName(value);
403 LOG(("\tName: %s\n", value.get()));
405 channel->GetContentType(value);
406 LOG(("\tContent-Type: %s\n", value.get()));
408 channel->GetContentCharset(value);
409 LOG(("\tContent-Charset: %s\n", value.get()));
411 int64_t length = -1;
412 if (NS_SUCCEEDED(channel->GetContentLength(&length))) {
413 LOG(("\tContent-Length: %lld\n", length));
414 } else {
415 LOG(("\tContent-Length: Unknown\n"));
419 nsCOMPtr<nsISupports> owner;
420 channel->GetOwner(getter_AddRefs(owner));
421 LOG(("\tChannel Owner: %x\n", owner.get()));
424 nsCOMPtr<nsIPropertyBag2> props = do_QueryInterface(request);
425 if (props) {
426 nsCOMPtr<nsIURI> foo;
427 props->GetPropertyAsInterface(NS_LITERAL_STRING("test.foo"),
428 NS_GET_IID(nsIURI),
429 getter_AddRefs(foo));
430 if (foo) {
431 nsAutoCString spec;
432 foo->GetSpec(spec);
433 LOG(("\ttest.foo: %s\n", spec.get()));
437 nsCOMPtr<nsIHttpChannelInternal> httpChannelInt(do_QueryInterface(request));
438 if (httpChannelInt) {
439 uint32_t majorVer, minorVer;
440 nsresult rv = httpChannelInt->GetResponseVersion(&majorVer, &minorVer);
441 if (NS_SUCCEEDED(rv)) {
442 LOG(("HTTP Response version: %u.%u\n", majorVer, minorVer));
445 nsCOMPtr<nsIHttpChannel> httpChannel(do_QueryInterface(request));
446 if (httpChannel) {
447 HeaderVisitor *visitor = new HeaderVisitor();
448 if (!visitor)
449 return NS_ERROR_OUT_OF_MEMORY;
450 NS_ADDREF(visitor);
452 LOG(("HTTP request headers:\n"));
453 httpChannel->VisitRequestHeaders(visitor);
455 LOG(("HTTP response headers:\n"));
456 httpChannel->VisitResponseHeaders(visitor);
458 NS_RELEASE(visitor);
461 nsCOMPtr<nsIResumableChannel> resChannel = do_QueryInterface(request);
462 if (resChannel) {
463 LOG(("Resumable entity identification:\n"));
464 nsAutoCString entityID;
465 nsresult rv = resChannel->GetEntityID(entityID);
466 if (NS_SUCCEEDED(rv)) {
467 LOG(("\t|%s|\n", entityID.get()));
469 else {
470 LOG(("\t<none>\n"));
474 return NS_OK;
477 NS_IMETHODIMP
478 InputTestConsumer::OnDataAvailable(nsIRequest *request,
479 nsISupports* context,
480 nsIInputStream *aIStream,
481 uint64_t aSourceOffset,
482 uint32_t aLength)
484 char buf[1025];
485 uint32_t amt, size;
486 nsresult rv;
487 URLLoadInfo* info = (URLLoadInfo*)context;
489 while (aLength) {
490 size = std::min<uint32_t>(aLength, sizeof(buf));
492 rv = aIStream->Read(buf, size, &amt);
493 if (NS_FAILED(rv)) {
494 NS_ASSERTION((NS_BASE_STREAM_WOULD_BLOCK != rv),
495 "The stream should never block.");
496 return rv;
498 if (gVerbose) {
499 buf[amt] = '\0';
500 puts(buf);
502 if (info) {
503 info->mBytesRead += amt;
506 aLength -= amt;
508 return NS_OK;
511 NS_IMETHODIMP
512 InputTestConsumer::OnStopRequest(nsIRequest *request, nsISupports* context,
513 nsresult aStatus)
515 LOG(("InputTestConsumer::OnStopRequest [status=%x]\n", aStatus));
517 URLLoadInfo* info = (URLLoadInfo*)context;
519 if (info) {
520 uint32_t httpStatus;
521 bool bHTTPURL = false;
523 info->mTotalTime = PR_Now() - info->mTotalTime;
525 double readTime = ((info->mTotalTime-info->mConnectTime)/1000.0)/1000.0;
527 nsCOMPtr<nsIHttpChannel> pHTTPCon(do_QueryInterface(request));
528 if (pHTTPCon) {
529 pHTTPCon->GetResponseStatus(&httpStatus);
530 bHTTPURL = true;
533 LOG(("\nFinished loading: %s Status Code: %x\n", info->Name(), aStatus));
534 if (bHTTPURL) {
535 LOG(("\tHTTP Status: %u\n", httpStatus));
537 if (NS_ERROR_UNKNOWN_HOST == aStatus ||
538 NS_ERROR_UNKNOWN_PROXY_HOST == aStatus) {
539 LOG(("\tDNS lookup failed.\n"));
541 LOG(("\tTime to connect: %.3f seconds\n", (info->mConnectTime/1000.0)/1000.0));
542 LOG(("\tTime to read: %.3f seconds.\n", readTime));
543 LOG(("\tRead: %lld bytes.\n", info->mBytesRead));
544 if (info->mBytesRead == int64_t(0)) {
545 } else if (readTime > 0.0) {
546 LOG(("\tThroughput: %.0f bps.\n", (double)(info->mBytesRead*int64_t(8))/readTime));
547 } else {
548 LOG(("\tThroughput: REAL FAST!!\n"));
551 nsCOMPtr<nsITimedChannel> timed(do_QueryInterface(request));
552 if (timed)
553 PrintTimingInformation(timed);
554 } else {
555 LOG(("\nFinished loading: UNKNOWN URL. Status Code: %x\n", aStatus));
558 if (--gKeepRunning == 0)
559 QuitPumpingEvents();
560 return NS_OK;
563 //-----------------------------------------------------------------------------
564 // NotificationCallbacks
565 //-----------------------------------------------------------------------------
567 class NotificationCallbacks MOZ_FINAL : public nsIInterfaceRequestor {
569 ~NotificationCallbacks() {}
571 public:
572 NS_DECL_ISUPPORTS
574 NotificationCallbacks() {
577 NS_IMETHOD GetInterface(const nsIID& iid, void* *result) {
578 nsresult rv = NS_ERROR_FAILURE;
580 if (iid.Equals(NS_GET_IID(nsIChannelEventSink))) {
581 TestChannelEventSink *sink;
583 sink = new TestChannelEventSink();
584 if (sink == nullptr)
585 return NS_ERROR_OUT_OF_MEMORY;
586 NS_ADDREF(sink);
587 rv = sink->QueryInterface(iid, result);
588 NS_RELEASE(sink);
591 if (iid.Equals(NS_GET_IID(nsIAuthPrompt))) {
592 TestAuthPrompt *prompt;
594 prompt = new TestAuthPrompt();
595 if (prompt == nullptr)
596 return NS_ERROR_OUT_OF_MEMORY;
597 NS_ADDREF(prompt);
598 rv = prompt->QueryInterface(iid, result);
599 NS_RELEASE(prompt);
601 return rv;
605 NS_IMPL_ISUPPORTS(NotificationCallbacks, nsIInterfaceRequestor)
607 //-----------------------------------------------------------------------------
608 // helpers...
609 //-----------------------------------------------------------------------------
611 nsresult StartLoadingURL(const char* aUrlString)
613 nsresult rv;
615 nsCOMPtr<nsIIOService> pService(do_GetService(kIOServiceCID, &rv));
616 if (pService) {
617 nsCOMPtr<nsIURI> pURL;
619 rv = pService->NewURI(nsDependentCString(aUrlString), nullptr, nullptr, getter_AddRefs(pURL));
620 if (NS_FAILED(rv)) {
621 LOG(("ERROR: NewURI failed for %s [rv=%x]\n", aUrlString));
622 return rv;
624 nsCOMPtr<nsIChannel> pChannel;
626 NotificationCallbacks* callbacks = new NotificationCallbacks();
627 if (!callbacks) {
628 LOG(("Failed to create a new consumer!"));
629 return NS_ERROR_OUT_OF_MEMORY;;
631 NS_ADDREF(callbacks);
633 // Async reading thru the calls of the event sink interface
634 rv = NS_NewChannel(getter_AddRefs(pChannel), pURL, pService,
635 nullptr, // loadGroup
636 callbacks); // notificationCallbacks
637 NS_RELEASE(callbacks);
638 if (NS_FAILED(rv)) {
639 LOG(("ERROR: NS_OpenURI failed for %s [rv=%x]\n", aUrlString, rv));
640 return rv;
643 nsCOMPtr<nsITimedChannel> timed(do_QueryInterface(pChannel));
644 if (timed)
645 timed->SetTimingEnabled(true);
647 nsCOMPtr<nsIWritablePropertyBag2> props = do_QueryInterface(pChannel);
648 if (props) {
649 rv = props->SetPropertyAsInterface(NS_LITERAL_STRING("test.foo"),
650 pURL);
651 if (NS_SUCCEEDED(rv)) {
652 LOG(("set prop 'test.foo'\n"));
657 You may optionally add/set other headers on this
658 request object. This is done by QI for the specific
659 protocolConnection.
661 nsCOMPtr<nsIHttpChannel> pHTTPCon(do_QueryInterface(pChannel));
663 if (pHTTPCon) {
664 // Setting a sample header.
665 rv = pHTTPCon->SetRequestHeader(NS_LITERAL_CSTRING("sample-header"),
666 NS_LITERAL_CSTRING("Sample-Value"),
667 false);
668 if (NS_FAILED(rv)) return rv;
670 InputTestConsumer* listener;
672 listener = new InputTestConsumer;
673 NS_IF_ADDREF(listener);
674 if (!listener) {
675 NS_ERROR("Failed to create a new stream listener!");
676 return NS_ERROR_OUT_OF_MEMORY;;
679 URLLoadInfo* info;
680 info = new URLLoadInfo(aUrlString);
681 NS_IF_ADDREF(info);
682 if (!info) {
683 NS_ERROR("Failed to create a load info!");
684 return NS_ERROR_OUT_OF_MEMORY;
687 if (gResume) {
688 nsCOMPtr<nsIResumableChannel> res = do_QueryInterface(pChannel);
689 if (!res) {
690 NS_ERROR("Channel is not resumable!");
691 return NS_ERROR_UNEXPECTED;
693 nsAutoCString id;
694 if (gEntityID)
695 id = gEntityID;
696 LOG(("* resuming at %llu bytes, with entity id |%s|\n", gStartAt, id.get()));
697 res->ResumeAt(gStartAt, id);
699 rv = pChannel->AsyncOpen(listener, // IStreamListener consumer
700 info);
702 if (NS_SUCCEEDED(rv)) {
703 gKeepRunning++;
705 else {
706 LOG(("ERROR: AsyncOpen failed [rv=%x]\n", rv));
708 NS_RELEASE(listener);
709 NS_RELEASE(info);
712 return rv;
715 static int32_t
716 FindChar(nsCString& buffer, char c)
718 const char *b;
719 int32_t len = NS_CStringGetData(buffer, &b);
721 for (int32_t offset = 0; offset < len; ++offset) {
722 if (b[offset] == c)
723 return offset;
726 return -1;
730 static void
731 StripChar(nsCString& buffer, char c)
733 const char *b;
734 uint32_t len = NS_CStringGetData(buffer, &b) - 1;
736 for (; len > 0; --len) {
737 if (b[len] == c) {
738 buffer.Cut(len, 1);
739 NS_CStringGetData(buffer, &b);
744 nsresult LoadURLsFromFile(char *aFileName)
746 nsresult rv = NS_OK;
747 int32_t len, offset;
748 PRFileDesc* fd;
749 char buffer[1024];
750 nsCString fileBuffer;
751 nsCString urlString;
753 fd = PR_Open(aFileName, PR_RDONLY, 777);
754 if (!fd) {
755 return NS_ERROR_FAILURE;
758 // Keep reading the file until EOF (or an error) is reached...
759 do {
760 len = PR_Read(fd, buffer, sizeof(buffer));
761 if (len>0) {
762 fileBuffer.Append(buffer, len);
763 // Treat each line as a URL...
764 while ((offset = FindChar(fileBuffer, '\n')) != -1) {
765 urlString = StringHead(fileBuffer, offset);
766 fileBuffer.Cut(0, offset+1);
768 StripChar(urlString, '\r');
769 if (urlString.Length()) {
770 LOG(("\t%s\n", urlString.get()));
771 rv = StartLoadingURL(urlString.get());
772 if (NS_FAILED(rv)) {
773 // No need to log an error -- StartLoadingURL already
774 // did that for us, probably.
775 PR_Close(fd);
776 return rv;
781 } while (len>0);
783 // If anything is left in the fileBuffer, treat it as a URL...
784 StripChar(fileBuffer, '\r');
785 if (fileBuffer.Length()) {
786 LOG(("\t%s\n", fileBuffer.get()));
787 StartLoadingURL(fileBuffer.get());
790 PR_Close(fd);
791 return NS_OK;
795 nsresult LoadURLFromConsole()
797 char buffer[1024];
798 printf("Enter URL (\"q\" to start): ");
799 unused << scanf("%s", buffer);
800 if (buffer[0]=='q')
801 gAskUserForInput = false;
802 else
803 StartLoadingURL(buffer);
804 return NS_OK;
807 } // namespace
809 using namespace TestProtocols;
812 main(int argc, char* argv[])
814 if (test_common_init(&argc, &argv) != 0)
815 return -1;
817 nsresult rv= (nsresult)-1;
818 if (argc < 2) {
819 printf("usage: %s [-verbose] [-file <name>] [-resume <startoffset>"
820 "[-entityid <entityid>]] [-proxy <proxy>] [-pac <pacURL>]"
821 "[-console] <url> <url> ... \n", argv[0]);
822 return -1;
825 #if defined(PR_LOGGING)
826 gTestLog = PR_NewLogModule("Test");
827 #endif
830 The following code only deals with XPCOM registration stuff. and setting
831 up the event queues. Copied from TestSocketIO.cpp
834 rv = NS_InitXPCOM2(nullptr, nullptr, nullptr);
835 if (NS_FAILED(rv)) return -1;
838 int i;
839 LOG(("Trying to load:\n"));
840 for (i=1; i<argc; i++) {
841 // Turn on verbose printing...
842 if (PL_strcasecmp(argv[i], "-verbose") == 0) {
843 gVerbose = true;
844 continue;
847 // Turn on netlib tracing...
848 if (PL_strcasecmp(argv[i], "-file") == 0) {
849 LoadURLsFromFile(argv[++i]);
850 continue;
853 if (PL_strcasecmp(argv[i], "-console") == 0) {
854 gAskUserForInput = true;
855 continue;
858 if (PL_strcasecmp(argv[i], "-resume") == 0) {
859 gResume = true;
860 PR_sscanf(argv[++i], "%llu", &gStartAt);
861 continue;
864 if (PL_strcasecmp(argv[i], "-entityid") == 0) {
865 gEntityID = argv[++i];
866 continue;
869 if (PL_strcasecmp(argv[i], "-proxy") == 0) {
870 SetHttpProxy(argv[++i]);
871 continue;
874 if (PL_strcasecmp(argv[i], "-pac") == 0) {
875 SetPACFile(argv[++i]);
876 continue;
879 LOG(("\t%s\n", argv[i]));
880 rv = StartLoadingURL(argv[i]);
882 // Enter the message pump to allow the URL load to proceed.
883 PumpEvents();
884 } // this scopes the nsCOMPtrs
885 // no nsCOMPtrs are allowed to be alive when you call NS_ShutdownXPCOM
886 NS_ShutdownXPCOM(nullptr);
887 return NS_FAILED(rv) ? -1 : 0;