netwerk/test/TestProtocols.cpp

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     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
    13 */
    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)
    66 //
    67 // set NSPR_LOG_MODULES=Test:5
    68 //
    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)
    90 {
    91   const char *colon = strchr(proxy, ':');
    92   if (!colon)
    93   {
    94     NS_WARNING("invalid proxy token; use host:port");
    95     return NS_ERROR_UNEXPECTED;
    96   }
    97   int port = atoi(colon + 1);
    98   if (port == 0)
    99   {
   100     NS_WARNING("invalid proxy port; must be an integer");
   101     return NS_ERROR_UNEXPECTED;
   102   }
   103   nsAutoCString proxyHost;
   104   proxyHost = Substring(proxy, colon);
   106   nsCOMPtr<nsIPrefBranch> prefs = do_GetService(NS_PREFSERVICE_CONTRACTID);
   107   if (prefs)
   108   {
   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
   112   }
   113   LOG(("connecting via proxy=%s:%d\n", proxyHost.get(), port));
   114   return NS_OK;
   115 }
   117 static nsresult
   118 SetPACFile(const char* pacURL)
   119 {
   120   nsCOMPtr<nsIPrefBranch> prefs = do_GetService(NS_PREFSERVICE_CONTRACTID);
   121   if (prefs)
   122   {
   123     prefs->SetCharPref("network.proxy.autoconfig_url", pacURL);
   124     prefs->SetIntPref("network.proxy.type", 2); // PAC file
   125   }
   126   LOG(("connecting using PAC file %s\n", pacURL));
   127   return NS_OK;
   128 }
   130 //-----------------------------------------------------------------------------
   131 // Timing information
   132 //-----------------------------------------------------------------------------
   134 void PrintTimingInformation(nsITimedChannel* channel) {
   135 #define PRINT_VALUE(property)                                              \
   136     {                                                                      \
   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"));                                    \
   147         }                                                                  \
   148     }
   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)
   161 }
   163 //-----------------------------------------------------------------------------
   164 // HeaderVisitor
   165 //-----------------------------------------------------------------------------
   167 class HeaderVisitor : public nsIHttpHeaderVisitor
   168 {
   169 public:
   170   NS_DECL_ISUPPORTS
   171   NS_DECL_NSIHTTPHEADERVISITOR
   173   HeaderVisitor() { }
   174   virtual ~HeaderVisitor() {}
   175 };
   176 NS_IMPL_ISUPPORTS(HeaderVisitor, nsIHttpHeaderVisitor)
   178 NS_IMETHODIMP
   179 HeaderVisitor::VisitHeader(const nsACString &header, const nsACString &value)
   180 {
   181   LOG(("  %s: %s\n",
   182     PromiseFlatCString(header).get(),
   183     PromiseFlatCString(value).get()));
   184   return NS_OK;
   185 }
   187 //-----------------------------------------------------------------------------
   188 // URLLoadInfo
   189 //-----------------------------------------------------------------------------
   191 class URLLoadInfo : public nsISupports
   192 {
   193 public:
   195   URLLoadInfo(const char* aUrl);
   196   virtual ~URLLoadInfo();
   198   // ISupports interface...
   199   NS_DECL_THREADSAFE_ISUPPORTS
   201   const char* Name() { return mURLString.get(); }
   202   int64_t   mBytesRead;
   203   PRTime    mTotalTime;
   204   PRTime    mConnectTime;
   205   nsCString mURLString;
   206 };
   208 URLLoadInfo::URLLoadInfo(const char *aUrl) : mURLString(aUrl)
   209 {
   210   mBytesRead = 0;
   211   mConnectTime = mTotalTime = PR_Now();
   212 }
   214 URLLoadInfo::~URLLoadInfo()
   215 {
   216 }
   219 NS_IMPL_ISUPPORTS0(URLLoadInfo)
   221 //-----------------------------------------------------------------------------
   222 // TestChannelEventSink
   223 //-----------------------------------------------------------------------------
   225 class TestChannelEventSink : public nsIChannelEventSink
   226 {
   227 public:
   228   NS_DECL_ISUPPORTS
   229   NS_DECL_NSICHANNELEVENTSINK
   231   TestChannelEventSink();
   232   virtual ~TestChannelEventSink();
   233 };
   235 TestChannelEventSink::TestChannelEventSink()
   236 {
   237 }
   239 TestChannelEventSink::~TestChannelEventSink()
   240 {
   241 }
   244 NS_IMPL_ISUPPORTS(TestChannelEventSink, nsIChannelEventSink)
   246 NS_IMETHODIMP
   247 TestChannelEventSink::AsyncOnChannelRedirect(nsIChannel *channel,
   248                                              nsIChannel *newChannel,
   249                                              uint32_t flags,
   250                                              nsIAsyncVerifyRedirectCallback *callback)
   251 {
   252     LOG(("\n+++ TestChannelEventSink::OnChannelRedirect (with flags %x) +++\n",
   253          flags));
   254     callback->OnRedirectVerifyCallback(NS_OK);
   255     return NS_OK;
   256 }
   258 //-----------------------------------------------------------------------------
   259 // TestAuthPrompt
   260 //-----------------------------------------------------------------------------
   262 class TestAuthPrompt : public nsIAuthPrompt
   263 {
   264 public:
   265   NS_DECL_ISUPPORTS
   266   NS_DECL_NSIAUTHPROMPT
   268   TestAuthPrompt();
   269   virtual ~TestAuthPrompt();
   270 };
   272 NS_IMPL_ISUPPORTS(TestAuthPrompt, nsIAuthPrompt)
   274 TestAuthPrompt::TestAuthPrompt()
   275 {
   276 }
   278 TestAuthPrompt::~TestAuthPrompt()
   279 {
   280 }
   282 NS_IMETHODIMP
   283 TestAuthPrompt::Prompt(const char16_t *dialogTitle,
   284                        const char16_t *text,
   285                        const char16_t *passwordRealm,
   286                        uint32_t savePassword,
   287                        const char16_t *defaultText,
   288                        char16_t **result,
   289                        bool *_retval)
   290 {
   291     *_retval = false;
   292     return NS_ERROR_NOT_IMPLEMENTED;
   293 }
   295 NS_IMETHODIMP
   296 TestAuthPrompt::PromptUsernameAndPassword(const char16_t *dialogTitle,
   297                                           const char16_t *dialogText,
   298                                           const char16_t *passwordRealm,
   299                                           uint32_t savePassword,
   300                                           char16_t **user,
   301                                           char16_t **pwd,
   302                                           bool *_retval)
   303 {
   304     NS_ConvertUTF16toUTF8 text(passwordRealm);
   305     printf("* --------------------------------------------------------------------------- *\n");
   306     printf("* Authentication Required [%s]\n", text.get());
   307     printf("* --------------------------------------------------------------------------- *\n");
   309     char buf[256];
   310     int n;
   312     printf("Enter username: ");
   313     unused << fgets(buf, sizeof(buf), stdin);
   314     n = strlen(buf);
   315     buf[n-1] = '\0'; // trim trailing newline
   316     *user = NS_StringCloneData(NS_ConvertUTF8toUTF16(buf));
   318     const char *p;
   319 #if defined(XP_UNIX) && !defined(ANDROID)
   320     p = getpass("Enter password: ");
   321 #else
   322     printf("Enter password: ");
   323     fgets(buf, sizeof(buf), stdin);
   324     n = strlen(buf);
   325     buf[n-1] = '\0'; // trim trailing newline
   326     p = buf;
   327 #endif
   328     *pwd = NS_StringCloneData(NS_ConvertUTF8toUTF16(p));
   330     // zap buf 
   331     memset(buf, 0, sizeof(buf));
   333     *_retval = true;
   334     return NS_OK;
   335 }
   337 NS_IMETHODIMP
   338 TestAuthPrompt::PromptPassword(const char16_t *dialogTitle,
   339                                const char16_t *text,
   340                                const char16_t *passwordRealm,
   341                                uint32_t savePassword,
   342                                char16_t **pwd,
   343                                bool *_retval)
   344 {
   345     *_retval = false;
   346     return NS_ERROR_NOT_IMPLEMENTED;
   347 }
   349 //-----------------------------------------------------------------------------
   350 // InputTestConsumer
   351 //-----------------------------------------------------------------------------
   353 class InputTestConsumer : public nsIStreamListener
   354 {
   355 public:
   357   InputTestConsumer();
   358   virtual ~InputTestConsumer();
   360   NS_DECL_ISUPPORTS
   361   NS_DECL_NSIREQUESTOBSERVER
   362   NS_DECL_NSISTREAMLISTENER
   363 };
   365 InputTestConsumer::InputTestConsumer()
   366 {
   367 }
   369 InputTestConsumer::~InputTestConsumer()
   370 {
   371 }
   373 NS_IMPL_ISUPPORTS(InputTestConsumer, nsIStreamListener, nsIRequestObserver)
   375 NS_IMETHODIMP
   376 InputTestConsumer::OnStartRequest(nsIRequest *request, nsISupports* context)
   377 {
   378   LOG(("InputTestConsumer::OnStartRequest\n"));
   380   URLLoadInfo* info = (URLLoadInfo*)context;
   381   if (info)
   382     info->mConnectTime = PR_Now() - info->mConnectTime;
   384   if (gVerbose) {
   385     LOG(("\nStarted loading: %s\n", info ? info->Name() : "UNKNOWN URL"));
   386   }
   388   nsAutoCString value;
   390   nsCOMPtr<nsIChannel> channel = do_QueryInterface(request);
   391   if (channel) {
   392     nsresult status;
   393     channel->GetStatus(&status);
   394     LOG(("Channel Status: %08x\n", status));
   395     if (NS_SUCCEEDED(status)) {
   396       LOG(("Channel Info:\n"));
   398       channel->GetName(value);
   399       LOG(("\tName: %s\n", value.get()));
   401       channel->GetContentType(value);
   402       LOG(("\tContent-Type: %s\n", value.get()));
   404       channel->GetContentCharset(value);
   405       LOG(("\tContent-Charset: %s\n", value.get()));
   407       int64_t length = -1;
   408       if (NS_SUCCEEDED(channel->GetContentLength(&length))) {
   409         LOG(("\tContent-Length: %lld\n", length));
   410       } else {
   411         LOG(("\tContent-Length: Unknown\n"));
   412       }
   413     }
   415     nsCOMPtr<nsISupports> owner;
   416     channel->GetOwner(getter_AddRefs(owner));
   417     LOG(("\tChannel Owner: %x\n", owner.get()));
   418   }
   420   nsCOMPtr<nsIPropertyBag2> props = do_QueryInterface(request);
   421   if (props) {
   422       nsCOMPtr<nsIURI> foo;
   423       props->GetPropertyAsInterface(NS_LITERAL_STRING("test.foo"),
   424                                     NS_GET_IID(nsIURI),
   425                                     getter_AddRefs(foo));
   426       if (foo) {
   427           nsAutoCString spec;
   428           foo->GetSpec(spec);
   429           LOG(("\ttest.foo: %s\n", spec.get()));
   430       }
   431   }
   433   nsCOMPtr<nsIHttpChannelInternal> httpChannelInt(do_QueryInterface(request));
   434   if (httpChannelInt) {
   435       uint32_t majorVer, minorVer;
   436       nsresult rv = httpChannelInt->GetResponseVersion(&majorVer, &minorVer);
   437       if (NS_SUCCEEDED(rv)) {
   438           LOG(("HTTP Response version: %u.%u\n", majorVer, minorVer));
   439       }
   440   }
   441   nsCOMPtr<nsIHttpChannel> httpChannel(do_QueryInterface(request));
   442   if (httpChannel) {
   443     HeaderVisitor *visitor = new HeaderVisitor();
   444     if (!visitor)
   445       return NS_ERROR_OUT_OF_MEMORY;
   446     NS_ADDREF(visitor);
   448     LOG(("HTTP request headers:\n"));
   449     httpChannel->VisitRequestHeaders(visitor);
   451     LOG(("HTTP response headers:\n"));
   452     httpChannel->VisitResponseHeaders(visitor);
   454     NS_RELEASE(visitor);
   455   }
   457   nsCOMPtr<nsIResumableChannel> resChannel = do_QueryInterface(request);
   458   if (resChannel) {
   459       LOG(("Resumable entity identification:\n"));
   460       nsAutoCString entityID;
   461       nsresult rv = resChannel->GetEntityID(entityID);
   462       if (NS_SUCCEEDED(rv)) {
   463           LOG(("\t|%s|\n", entityID.get()));
   464       }
   465       else {
   466           LOG(("\t<none>\n"));
   467       }
   468   }
   470   return NS_OK;
   471 }
   473 NS_IMETHODIMP
   474 InputTestConsumer::OnDataAvailable(nsIRequest *request, 
   475                                    nsISupports* context,
   476                                    nsIInputStream *aIStream, 
   477                                    uint64_t aSourceOffset,
   478                                    uint32_t aLength)
   479 {
   480   char buf[1025];
   481   uint32_t amt, size;
   482   nsresult rv;
   483   URLLoadInfo* info = (URLLoadInfo*)context;
   485   while (aLength) {
   486     size = std::min<uint32_t>(aLength, sizeof(buf));
   488     rv = aIStream->Read(buf, size, &amt);
   489     if (NS_FAILED(rv)) {
   490       NS_ASSERTION((NS_BASE_STREAM_WOULD_BLOCK != rv), 
   491                    "The stream should never block.");
   492       return rv;
   493     }
   494     if (gVerbose) {
   495       buf[amt] = '\0';
   496       puts(buf);
   497     }
   498     if (info) {
   499       info->mBytesRead += amt;
   500     }
   502     aLength -= amt;
   503   }
   504   return NS_OK;
   505 }
   507 NS_IMETHODIMP
   508 InputTestConsumer::OnStopRequest(nsIRequest *request, nsISupports* context,
   509                                  nsresult aStatus)
   510 {
   511   LOG(("InputTestConsumer::OnStopRequest [status=%x]\n", aStatus));
   513   URLLoadInfo* info = (URLLoadInfo*)context;
   515   if (info) {
   516     uint32_t httpStatus;
   517     bool bHTTPURL = false;
   519     info->mTotalTime = PR_Now() - info->mTotalTime;
   521     double readTime = ((info->mTotalTime-info->mConnectTime)/1000.0)/1000.0;
   523     nsCOMPtr<nsIHttpChannel> pHTTPCon(do_QueryInterface(request));
   524     if (pHTTPCon) {
   525         pHTTPCon->GetResponseStatus(&httpStatus);
   526         bHTTPURL = true;
   527     }
   529     LOG(("\nFinished loading: %s  Status Code: %x\n", info->Name(), aStatus));
   530     if (bHTTPURL) {
   531       LOG(("\tHTTP Status: %u\n", httpStatus));
   532     }
   533     if (NS_ERROR_UNKNOWN_HOST == aStatus ||
   534         NS_ERROR_UNKNOWN_PROXY_HOST == aStatus) {
   535       LOG(("\tDNS lookup failed.\n"));
   536     }
   537     LOG(("\tTime to connect: %.3f seconds\n", (info->mConnectTime/1000.0)/1000.0));
   538     LOG(("\tTime to read: %.3f seconds.\n", readTime));
   539     LOG(("\tRead: %lld bytes.\n", info->mBytesRead));
   540     if (info->mBytesRead == int64_t(0)) {
   541     } else if (readTime > 0.0) {
   542       LOG(("\tThroughput: %.0f bps.\n", (double)(info->mBytesRead*int64_t(8))/readTime));
   543     } else {
   544       LOG(("\tThroughput: REAL FAST!!\n"));
   545     }
   547     nsCOMPtr<nsITimedChannel> timed(do_QueryInterface(request));
   548     if (timed)
   549         PrintTimingInformation(timed);
   550   } else {
   551     LOG(("\nFinished loading: UNKNOWN URL. Status Code: %x\n", aStatus));
   552   }
   554   if (--gKeepRunning == 0)
   555     QuitPumpingEvents();
   556   return NS_OK;
   557 }
   559 //-----------------------------------------------------------------------------
   560 // NotificationCallbacks
   561 //-----------------------------------------------------------------------------
   563 class NotificationCallbacks MOZ_FINAL : public nsIInterfaceRequestor {
   564 public:
   565     NS_DECL_ISUPPORTS
   567     NotificationCallbacks() {
   568     }
   570     NS_IMETHOD GetInterface(const nsIID& iid, void* *result) {
   571         nsresult rv = NS_ERROR_FAILURE;
   573         if (iid.Equals(NS_GET_IID(nsIChannelEventSink))) {
   574           TestChannelEventSink *sink;
   576           sink = new TestChannelEventSink();
   577           if (sink == nullptr)
   578             return NS_ERROR_OUT_OF_MEMORY;
   579           NS_ADDREF(sink);
   580           rv = sink->QueryInterface(iid, result);
   581           NS_RELEASE(sink);
   582         }
   584         if (iid.Equals(NS_GET_IID(nsIAuthPrompt))) {
   585           TestAuthPrompt *prompt;
   587           prompt = new TestAuthPrompt();
   588           if (prompt == nullptr)
   589             return NS_ERROR_OUT_OF_MEMORY;
   590           NS_ADDREF(prompt);
   591           rv = prompt->QueryInterface(iid, result);
   592           NS_RELEASE(prompt);
   593         }
   594         return rv;
   595     }
   596 };
   598 NS_IMPL_ISUPPORTS(NotificationCallbacks, nsIInterfaceRequestor)
   600 //-----------------------------------------------------------------------------
   601 // helpers...
   602 //-----------------------------------------------------------------------------
   604 nsresult StartLoadingURL(const char* aUrlString)
   605 {
   606     nsresult rv;
   608     nsCOMPtr<nsIIOService> pService(do_GetService(kIOServiceCID, &rv));
   609     if (pService) {
   610         nsCOMPtr<nsIURI> pURL;
   612         rv = pService->NewURI(nsDependentCString(aUrlString), nullptr, nullptr, getter_AddRefs(pURL));
   613         if (NS_FAILED(rv)) {
   614             LOG(("ERROR: NewURI failed for %s [rv=%x]\n", aUrlString));
   615             return rv;
   616         }
   617         nsCOMPtr<nsIChannel> pChannel;
   619         NotificationCallbacks* callbacks = new NotificationCallbacks();
   620         if (!callbacks) {
   621             LOG(("Failed to create a new consumer!"));
   622             return NS_ERROR_OUT_OF_MEMORY;;
   623         }
   624         NS_ADDREF(callbacks);
   626         // Async reading thru the calls of the event sink interface
   627         rv = NS_NewChannel(getter_AddRefs(pChannel), pURL, pService,
   628                            nullptr,     // loadGroup
   629                            callbacks); // notificationCallbacks
   630         NS_RELEASE(callbacks);
   631         if (NS_FAILED(rv)) {
   632             LOG(("ERROR: NS_OpenURI failed for %s [rv=%x]\n", aUrlString, rv));
   633             return rv;
   634         }
   636         nsCOMPtr<nsITimedChannel> timed(do_QueryInterface(pChannel));
   637         if (timed)
   638             timed->SetTimingEnabled(true);
   640         nsCOMPtr<nsIWritablePropertyBag2> props = do_QueryInterface(pChannel);
   641         if (props) {
   642             rv = props->SetPropertyAsInterface(NS_LITERAL_STRING("test.foo"),
   643                                                pURL);
   644             if (NS_SUCCEEDED(rv)) {
   645                 LOG(("set prop 'test.foo'\n"));
   646             }
   647         }
   649         /* 
   650            You may optionally add/set other headers on this
   651            request object. This is done by QI for the specific
   652            protocolConnection.
   653         */
   654         nsCOMPtr<nsIHttpChannel> pHTTPCon(do_QueryInterface(pChannel));
   656         if (pHTTPCon) {
   657             // Setting a sample header.
   658             rv = pHTTPCon->SetRequestHeader(NS_LITERAL_CSTRING("sample-header"),
   659                                             NS_LITERAL_CSTRING("Sample-Value"),
   660                                             false);
   661             if (NS_FAILED(rv)) return rv;
   662         }            
   663         InputTestConsumer* listener;
   665         listener = new InputTestConsumer;
   666         NS_IF_ADDREF(listener);
   667         if (!listener) {
   668             NS_ERROR("Failed to create a new stream listener!");
   669             return NS_ERROR_OUT_OF_MEMORY;;
   670         }
   672         URLLoadInfo* info;
   673         info = new URLLoadInfo(aUrlString);
   674         NS_IF_ADDREF(info);
   675         if (!info) {
   676             NS_ERROR("Failed to create a load info!");
   677             return NS_ERROR_OUT_OF_MEMORY;
   678         }
   680         if (gResume) {
   681             nsCOMPtr<nsIResumableChannel> res = do_QueryInterface(pChannel);
   682             if (!res) {
   683                 NS_ERROR("Channel is not resumable!");
   684                 return NS_ERROR_UNEXPECTED;
   685             }
   686             nsAutoCString id;
   687             if (gEntityID)
   688                 id = gEntityID;
   689             LOG(("* resuming at %llu bytes, with entity id |%s|\n", gStartAt, id.get()));
   690             res->ResumeAt(gStartAt, id);
   691         }
   692         rv = pChannel->AsyncOpen(listener,  // IStreamListener consumer
   693                                  info);
   695         if (NS_SUCCEEDED(rv)) {
   696             gKeepRunning++;
   697         }
   698         else {
   699             LOG(("ERROR: AsyncOpen failed [rv=%x]\n", rv));
   700         }
   701         NS_RELEASE(listener);
   702         NS_RELEASE(info);
   703     }
   705     return rv;
   706 }
   708 static int32_t
   709 FindChar(nsCString& buffer, char c)
   710 {
   711     const char *b;
   712     int32_t len = NS_CStringGetData(buffer, &b);
   714     for (int32_t offset = 0; offset < len; ++offset) {
   715         if (b[offset] == c)
   716             return offset;
   717     }
   719     return -1;
   720 }
   723 static void
   724 StripChar(nsCString& buffer, char c)
   725 {
   726     const char *b;
   727     uint32_t len = NS_CStringGetData(buffer, &b) - 1;
   729     for (; len > 0; --len) {
   730         if (b[len] == c) {
   731             buffer.Cut(len, 1);
   732             NS_CStringGetData(buffer, &b);
   733         }
   734     }
   735 }
   737 nsresult LoadURLsFromFile(char *aFileName)
   738 {
   739     nsresult rv = NS_OK;
   740     int32_t len, offset;
   741     PRFileDesc* fd;
   742     char buffer[1024];
   743     nsCString fileBuffer;
   744     nsCString urlString;
   746     fd = PR_Open(aFileName, PR_RDONLY, 777);
   747     if (!fd) {
   748         return NS_ERROR_FAILURE;
   749     }
   751     // Keep reading the file until EOF (or an error) is reached...        
   752     do {
   753         len = PR_Read(fd, buffer, sizeof(buffer));
   754         if (len>0) {
   755             fileBuffer.Append(buffer, len);
   756             // Treat each line as a URL...
   757             while ((offset = FindChar(fileBuffer, '\n')) != -1) {
   758                 urlString = StringHead(fileBuffer, offset);
   759                 fileBuffer.Cut(0, offset+1);
   761                 StripChar(urlString, '\r');
   762                 if (urlString.Length()) {
   763                     LOG(("\t%s\n", urlString.get()));
   764                     rv = StartLoadingURL(urlString.get());
   765                     if (NS_FAILED(rv)) {
   766                         // No need to log an error -- StartLoadingURL already
   767                         // did that for us, probably.
   768                         PR_Close(fd);
   769                         return rv;
   770                     }
   771                 }
   772             }
   773         }
   774     } while (len>0);
   776     // If anything is left in the fileBuffer, treat it as a URL...
   777     StripChar(fileBuffer, '\r');
   778     if (fileBuffer.Length()) {
   779         LOG(("\t%s\n", fileBuffer.get()));
   780         StartLoadingURL(fileBuffer.get());
   781     }
   783     PR_Close(fd);
   784     return NS_OK;
   785 }
   788 nsresult LoadURLFromConsole()
   789 {
   790     char buffer[1024];
   791     printf("Enter URL (\"q\" to start): ");
   792     unused << scanf("%s", buffer);
   793     if (buffer[0]=='q') 
   794         gAskUserForInput = false;
   795     else
   796         StartLoadingURL(buffer);
   797     return NS_OK;
   798 }
   800 } // namespace
   802 using namespace TestProtocols;
   804 int
   805 main(int argc, char* argv[])
   806 {
   807     if (test_common_init(&argc, &argv) != 0)
   808         return -1;
   810     nsresult rv= (nsresult)-1;
   811     if (argc < 2) {
   812         printf("usage: %s [-verbose] [-file <name>] [-resume <startoffset>"
   813                "[-entityid <entityid>]] [-proxy <proxy>] [-pac <pacURL>]"
   814                "[-console] <url> <url> ... \n", argv[0]);
   815         return -1;
   816     }
   818 #if defined(PR_LOGGING)
   819     gTestLog = PR_NewLogModule("Test");
   820 #endif
   822     /* 
   823       The following code only deals with XPCOM registration stuff. and setting
   824       up the event queues. Copied from TestSocketIO.cpp
   825     */
   827     rv = NS_InitXPCOM2(nullptr, nullptr, nullptr);
   828     if (NS_FAILED(rv)) return -1;
   830     {
   831         int i;
   832         LOG(("Trying to load:\n"));
   833         for (i=1; i<argc; i++) {
   834             // Turn on verbose printing...
   835             if (PL_strcasecmp(argv[i], "-verbose") == 0) {
   836                 gVerbose = true;
   837                 continue;
   838             }
   840             // Turn on netlib tracing...
   841             if (PL_strcasecmp(argv[i], "-file") == 0) {
   842                 LoadURLsFromFile(argv[++i]);
   843                 continue;
   844             }
   846             if (PL_strcasecmp(argv[i], "-console") == 0) {
   847                 gAskUserForInput = true;
   848                 continue;
   849             }
   851             if (PL_strcasecmp(argv[i], "-resume") == 0) {
   852                 gResume = true;
   853                 PR_sscanf(argv[++i], "%llu", &gStartAt);
   854                 continue;
   855             }
   857             if (PL_strcasecmp(argv[i], "-entityid") == 0) {
   858                 gEntityID = argv[++i];
   859                 continue;
   860             }
   862             if (PL_strcasecmp(argv[i], "-proxy") == 0) {
   863                 SetHttpProxy(argv[++i]);
   864                 continue;
   865             }
   867             if (PL_strcasecmp(argv[i], "-pac") == 0) {
   868                 SetPACFile(argv[++i]);
   869                 continue;
   870             }
   872             LOG(("\t%s\n", argv[i]));
   873             rv = StartLoadingURL(argv[i]);
   874         }
   875         // Enter the message pump to allow the URL load to proceed.
   876         PumpEvents();
   877     } // this scopes the nsCOMPtrs
   878     // no nsCOMPtrs are allowed to be alive when you call NS_ShutdownXPCOM
   879     NS_ShutdownXPCOM(nullptr);
   880     return NS_FAILED(rv) ? -1 : 0;
   881 }

mercurial