netwerk/test/TestProtocols.cpp

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/netwerk/test/TestProtocols.cpp	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,881 @@
     1.4 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
     1.5 +/* vim: set ts=2 sw=2 et cindent: */
     1.6 +/* This Source Code Form is subject to the terms of the Mozilla Public
     1.7 + * License, v. 2.0. If a copy of the MPL was not distributed with this
     1.8 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     1.9 +
    1.10 +/* 
    1.11 +    The TestProtocols tests the basic protocols architecture and can 
    1.12 +    be used to test individual protocols as well. If this grows too
    1.13 +    big then we should split it to individual protocols. 
    1.14 +
    1.15 +    -Gagan Saksena 04/29/99
    1.16 +*/
    1.17 +
    1.18 +#include "TestCommon.h"
    1.19 +#include <algorithm>
    1.20 +
    1.21 +#define FORCE_PR_LOG
    1.22 +#include <stdio.h>
    1.23 +#ifdef WIN32 
    1.24 +#include <windows.h>
    1.25 +#endif
    1.26 +#ifdef XP_UNIX
    1.27 +#include <unistd.h>
    1.28 +#endif
    1.29 +#include "nspr.h"
    1.30 +#include "nscore.h"
    1.31 +#include "nsCOMPtr.h"
    1.32 +#include "nsIIOService.h"
    1.33 +#include "nsIServiceManager.h"
    1.34 +#include "nsIStreamListener.h"
    1.35 +#include "nsIInputStream.h"
    1.36 +#include "nsIInputStream.h"
    1.37 +#include "nsCRT.h"
    1.38 +#include "nsIChannel.h"
    1.39 +#include "nsIResumableChannel.h"
    1.40 +#include "nsIURL.h"
    1.41 +#include "nsIHttpChannel.h"
    1.42 +#include "nsIHttpChannelInternal.h"
    1.43 +#include "nsIHttpHeaderVisitor.h"
    1.44 +#include "nsIChannelEventSink.h" 
    1.45 +#include "nsIAsyncVerifyRedirectCallback.h"
    1.46 +#include "nsIInterfaceRequestor.h" 
    1.47 +#include "nsIInterfaceRequestorUtils.h"
    1.48 +#include "nsIDNSService.h" 
    1.49 +#include "nsIAuthPrompt.h"
    1.50 +#include "nsIPrefService.h"
    1.51 +#include "nsIPrefBranch.h"
    1.52 +#include "nsIPropertyBag2.h"
    1.53 +#include "nsIWritablePropertyBag2.h"
    1.54 +#include "nsITimedChannel.h"
    1.55 +#include "nsChannelProperties.h"
    1.56 +#include "mozilla/Attributes.h"
    1.57 +#include "mozilla/unused.h"
    1.58 +
    1.59 +#include "nsISimpleEnumerator.h"
    1.60 +#include "nsStringAPI.h"
    1.61 +#include "nsNetUtil.h"
    1.62 +#include "prlog.h"
    1.63 +
    1.64 +using namespace mozilla;
    1.65 +
    1.66 +namespace TestProtocols {
    1.67 +
    1.68 +#if defined(PR_LOGGING)
    1.69 +//
    1.70 +// set NSPR_LOG_MODULES=Test:5
    1.71 +//
    1.72 +static PRLogModuleInfo *gTestLog = nullptr;
    1.73 +#endif
    1.74 +#define LOG(args) PR_LOG(gTestLog, PR_LOG_DEBUG, args)
    1.75 +
    1.76 +static NS_DEFINE_CID(kIOServiceCID,              NS_IOSERVICE_CID);
    1.77 +
    1.78 +//static PRTime gElapsedTime; // enable when we time it...
    1.79 +static int gKeepRunning = 0;
    1.80 +static bool gVerbose = false;
    1.81 +static bool gAskUserForInput = false;
    1.82 +static bool gResume = false;
    1.83 +static uint64_t gStartAt = 0;
    1.84 +
    1.85 +static const char* gEntityID;
    1.86 +
    1.87 +//-----------------------------------------------------------------------------
    1.88 +// Set proxy preferences for testing
    1.89 +//-----------------------------------------------------------------------------
    1.90 +
    1.91 +static nsresult
    1.92 +SetHttpProxy(const char *proxy)
    1.93 +{
    1.94 +  const char *colon = strchr(proxy, ':');
    1.95 +  if (!colon)
    1.96 +  {
    1.97 +    NS_WARNING("invalid proxy token; use host:port");
    1.98 +    return NS_ERROR_UNEXPECTED;
    1.99 +  }
   1.100 +  int port = atoi(colon + 1);
   1.101 +  if (port == 0)
   1.102 +  {
   1.103 +    NS_WARNING("invalid proxy port; must be an integer");
   1.104 +    return NS_ERROR_UNEXPECTED;
   1.105 +  }
   1.106 +  nsAutoCString proxyHost;
   1.107 +  proxyHost = Substring(proxy, colon);
   1.108 +
   1.109 +  nsCOMPtr<nsIPrefBranch> prefs = do_GetService(NS_PREFSERVICE_CONTRACTID);
   1.110 +  if (prefs)
   1.111 +  {
   1.112 +    prefs->SetCharPref("network.proxy.http", proxyHost.get());
   1.113 +    prefs->SetIntPref("network.proxy.http_port", port);
   1.114 +    prefs->SetIntPref("network.proxy.type", 1); // manual proxy config
   1.115 +  }
   1.116 +  LOG(("connecting via proxy=%s:%d\n", proxyHost.get(), port));
   1.117 +  return NS_OK;
   1.118 +}
   1.119 +
   1.120 +static nsresult
   1.121 +SetPACFile(const char* pacURL)
   1.122 +{
   1.123 +  nsCOMPtr<nsIPrefBranch> prefs = do_GetService(NS_PREFSERVICE_CONTRACTID);
   1.124 +  if (prefs)
   1.125 +  {
   1.126 +    prefs->SetCharPref("network.proxy.autoconfig_url", pacURL);
   1.127 +    prefs->SetIntPref("network.proxy.type", 2); // PAC file
   1.128 +  }
   1.129 +  LOG(("connecting using PAC file %s\n", pacURL));
   1.130 +  return NS_OK;
   1.131 +}
   1.132 +
   1.133 +//-----------------------------------------------------------------------------
   1.134 +// Timing information
   1.135 +//-----------------------------------------------------------------------------
   1.136 +
   1.137 +void PrintTimingInformation(nsITimedChannel* channel) {
   1.138 +#define PRINT_VALUE(property)                                              \
   1.139 +    {                                                                      \
   1.140 +        PRTime value;                                                      \
   1.141 +        channel->Get##property(&value);                                    \
   1.142 +        if (value) {                                                       \
   1.143 +          PRExplodedTime exploded;                                         \
   1.144 +          PR_ExplodeTime(value, PR_LocalTimeParameters, &exploded);        \
   1.145 +          char buf[256];                                                   \
   1.146 +          PR_FormatTime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S", &exploded); \
   1.147 +          LOG(("  " #property ":\t%s (%i usec)", buf, exploded.tm_usec));  \
   1.148 +        } else {                                                           \
   1.149 +          LOG(("  " #property ":\t0"));                                    \
   1.150 +        }                                                                  \
   1.151 +    }
   1.152 +    LOG(("Timing data:"));
   1.153 +    PRINT_VALUE(ChannelCreationTime)
   1.154 +    PRINT_VALUE(AsyncOpenTime)
   1.155 +    PRINT_VALUE(DomainLookupStartTime)
   1.156 +    PRINT_VALUE(DomainLookupEndTime)
   1.157 +    PRINT_VALUE(ConnectStartTime)
   1.158 +    PRINT_VALUE(ConnectEndTime)
   1.159 +    PRINT_VALUE(RequestStartTime)
   1.160 +    PRINT_VALUE(ResponseStartTime)
   1.161 +    PRINT_VALUE(ResponseEndTime)
   1.162 +    PRINT_VALUE(CacheReadStartTime)
   1.163 +    PRINT_VALUE(CacheReadEndTime)
   1.164 +}
   1.165 +
   1.166 +//-----------------------------------------------------------------------------
   1.167 +// HeaderVisitor
   1.168 +//-----------------------------------------------------------------------------
   1.169 +
   1.170 +class HeaderVisitor : public nsIHttpHeaderVisitor
   1.171 +{
   1.172 +public:
   1.173 +  NS_DECL_ISUPPORTS
   1.174 +  NS_DECL_NSIHTTPHEADERVISITOR
   1.175 +
   1.176 +  HeaderVisitor() { }
   1.177 +  virtual ~HeaderVisitor() {}
   1.178 +};
   1.179 +NS_IMPL_ISUPPORTS(HeaderVisitor, nsIHttpHeaderVisitor)
   1.180 +
   1.181 +NS_IMETHODIMP
   1.182 +HeaderVisitor::VisitHeader(const nsACString &header, const nsACString &value)
   1.183 +{
   1.184 +  LOG(("  %s: %s\n",
   1.185 +    PromiseFlatCString(header).get(),
   1.186 +    PromiseFlatCString(value).get()));
   1.187 +  return NS_OK;
   1.188 +}
   1.189 +
   1.190 +//-----------------------------------------------------------------------------
   1.191 +// URLLoadInfo
   1.192 +//-----------------------------------------------------------------------------
   1.193 +
   1.194 +class URLLoadInfo : public nsISupports
   1.195 +{
   1.196 +public:
   1.197 +
   1.198 +  URLLoadInfo(const char* aUrl);
   1.199 +  virtual ~URLLoadInfo();
   1.200 +
   1.201 +  // ISupports interface...
   1.202 +  NS_DECL_THREADSAFE_ISUPPORTS
   1.203 +
   1.204 +  const char* Name() { return mURLString.get(); }
   1.205 +  int64_t   mBytesRead;
   1.206 +  PRTime    mTotalTime;
   1.207 +  PRTime    mConnectTime;
   1.208 +  nsCString mURLString;
   1.209 +};
   1.210 +
   1.211 +URLLoadInfo::URLLoadInfo(const char *aUrl) : mURLString(aUrl)
   1.212 +{
   1.213 +  mBytesRead = 0;
   1.214 +  mConnectTime = mTotalTime = PR_Now();
   1.215 +}
   1.216 +
   1.217 +URLLoadInfo::~URLLoadInfo()
   1.218 +{
   1.219 +}
   1.220 +
   1.221 +
   1.222 +NS_IMPL_ISUPPORTS0(URLLoadInfo)
   1.223 +
   1.224 +//-----------------------------------------------------------------------------
   1.225 +// TestChannelEventSink
   1.226 +//-----------------------------------------------------------------------------
   1.227 +
   1.228 +class TestChannelEventSink : public nsIChannelEventSink
   1.229 +{
   1.230 +public:
   1.231 +  NS_DECL_ISUPPORTS
   1.232 +  NS_DECL_NSICHANNELEVENTSINK
   1.233 +
   1.234 +  TestChannelEventSink();
   1.235 +  virtual ~TestChannelEventSink();
   1.236 +};
   1.237 +
   1.238 +TestChannelEventSink::TestChannelEventSink()
   1.239 +{
   1.240 +}
   1.241 +
   1.242 +TestChannelEventSink::~TestChannelEventSink()
   1.243 +{
   1.244 +}
   1.245 +
   1.246 +
   1.247 +NS_IMPL_ISUPPORTS(TestChannelEventSink, nsIChannelEventSink)
   1.248 +
   1.249 +NS_IMETHODIMP
   1.250 +TestChannelEventSink::AsyncOnChannelRedirect(nsIChannel *channel,
   1.251 +                                             nsIChannel *newChannel,
   1.252 +                                             uint32_t flags,
   1.253 +                                             nsIAsyncVerifyRedirectCallback *callback)
   1.254 +{
   1.255 +    LOG(("\n+++ TestChannelEventSink::OnChannelRedirect (with flags %x) +++\n",
   1.256 +         flags));
   1.257 +    callback->OnRedirectVerifyCallback(NS_OK);
   1.258 +    return NS_OK;
   1.259 +}
   1.260 +
   1.261 +//-----------------------------------------------------------------------------
   1.262 +// TestAuthPrompt
   1.263 +//-----------------------------------------------------------------------------
   1.264 +
   1.265 +class TestAuthPrompt : public nsIAuthPrompt
   1.266 +{
   1.267 +public:
   1.268 +  NS_DECL_ISUPPORTS
   1.269 +  NS_DECL_NSIAUTHPROMPT
   1.270 +
   1.271 +  TestAuthPrompt();
   1.272 +  virtual ~TestAuthPrompt();
   1.273 +};
   1.274 +
   1.275 +NS_IMPL_ISUPPORTS(TestAuthPrompt, nsIAuthPrompt)
   1.276 +
   1.277 +TestAuthPrompt::TestAuthPrompt()
   1.278 +{
   1.279 +}
   1.280 +
   1.281 +TestAuthPrompt::~TestAuthPrompt()
   1.282 +{
   1.283 +}
   1.284 +
   1.285 +NS_IMETHODIMP
   1.286 +TestAuthPrompt::Prompt(const char16_t *dialogTitle,
   1.287 +                       const char16_t *text,
   1.288 +                       const char16_t *passwordRealm,
   1.289 +                       uint32_t savePassword,
   1.290 +                       const char16_t *defaultText,
   1.291 +                       char16_t **result,
   1.292 +                       bool *_retval)
   1.293 +{
   1.294 +    *_retval = false;
   1.295 +    return NS_ERROR_NOT_IMPLEMENTED;
   1.296 +}
   1.297 +
   1.298 +NS_IMETHODIMP
   1.299 +TestAuthPrompt::PromptUsernameAndPassword(const char16_t *dialogTitle,
   1.300 +                                          const char16_t *dialogText,
   1.301 +                                          const char16_t *passwordRealm,
   1.302 +                                          uint32_t savePassword,
   1.303 +                                          char16_t **user,
   1.304 +                                          char16_t **pwd,
   1.305 +                                          bool *_retval)
   1.306 +{
   1.307 +    NS_ConvertUTF16toUTF8 text(passwordRealm);
   1.308 +    printf("* --------------------------------------------------------------------------- *\n");
   1.309 +    printf("* Authentication Required [%s]\n", text.get());
   1.310 +    printf("* --------------------------------------------------------------------------- *\n");
   1.311 +
   1.312 +    char buf[256];
   1.313 +    int n;
   1.314 +
   1.315 +    printf("Enter username: ");
   1.316 +    unused << fgets(buf, sizeof(buf), stdin);
   1.317 +    n = strlen(buf);
   1.318 +    buf[n-1] = '\0'; // trim trailing newline
   1.319 +    *user = NS_StringCloneData(NS_ConvertUTF8toUTF16(buf));
   1.320 +
   1.321 +    const char *p;
   1.322 +#if defined(XP_UNIX) && !defined(ANDROID)
   1.323 +    p = getpass("Enter password: ");
   1.324 +#else
   1.325 +    printf("Enter password: ");
   1.326 +    fgets(buf, sizeof(buf), stdin);
   1.327 +    n = strlen(buf);
   1.328 +    buf[n-1] = '\0'; // trim trailing newline
   1.329 +    p = buf;
   1.330 +#endif
   1.331 +    *pwd = NS_StringCloneData(NS_ConvertUTF8toUTF16(p));
   1.332 +
   1.333 +    // zap buf 
   1.334 +    memset(buf, 0, sizeof(buf));
   1.335 +
   1.336 +    *_retval = true;
   1.337 +    return NS_OK;
   1.338 +}
   1.339 +
   1.340 +NS_IMETHODIMP
   1.341 +TestAuthPrompt::PromptPassword(const char16_t *dialogTitle,
   1.342 +                               const char16_t *text,
   1.343 +                               const char16_t *passwordRealm,
   1.344 +                               uint32_t savePassword,
   1.345 +                               char16_t **pwd,
   1.346 +                               bool *_retval)
   1.347 +{
   1.348 +    *_retval = false;
   1.349 +    return NS_ERROR_NOT_IMPLEMENTED;
   1.350 +}
   1.351 +
   1.352 +//-----------------------------------------------------------------------------
   1.353 +// InputTestConsumer
   1.354 +//-----------------------------------------------------------------------------
   1.355 +
   1.356 +class InputTestConsumer : public nsIStreamListener
   1.357 +{
   1.358 +public:
   1.359 +
   1.360 +  InputTestConsumer();
   1.361 +  virtual ~InputTestConsumer();
   1.362 +
   1.363 +  NS_DECL_ISUPPORTS
   1.364 +  NS_DECL_NSIREQUESTOBSERVER
   1.365 +  NS_DECL_NSISTREAMLISTENER
   1.366 +};
   1.367 +
   1.368 +InputTestConsumer::InputTestConsumer()
   1.369 +{
   1.370 +}
   1.371 +
   1.372 +InputTestConsumer::~InputTestConsumer()
   1.373 +{
   1.374 +}
   1.375 +
   1.376 +NS_IMPL_ISUPPORTS(InputTestConsumer, nsIStreamListener, nsIRequestObserver)
   1.377 +
   1.378 +NS_IMETHODIMP
   1.379 +InputTestConsumer::OnStartRequest(nsIRequest *request, nsISupports* context)
   1.380 +{
   1.381 +  LOG(("InputTestConsumer::OnStartRequest\n"));
   1.382 +
   1.383 +  URLLoadInfo* info = (URLLoadInfo*)context;
   1.384 +  if (info)
   1.385 +    info->mConnectTime = PR_Now() - info->mConnectTime;
   1.386 +
   1.387 +  if (gVerbose) {
   1.388 +    LOG(("\nStarted loading: %s\n", info ? info->Name() : "UNKNOWN URL"));
   1.389 +  }
   1.390 +
   1.391 +  nsAutoCString value;
   1.392 +
   1.393 +  nsCOMPtr<nsIChannel> channel = do_QueryInterface(request);
   1.394 +  if (channel) {
   1.395 +    nsresult status;
   1.396 +    channel->GetStatus(&status);
   1.397 +    LOG(("Channel Status: %08x\n", status));
   1.398 +    if (NS_SUCCEEDED(status)) {
   1.399 +      LOG(("Channel Info:\n"));
   1.400 +
   1.401 +      channel->GetName(value);
   1.402 +      LOG(("\tName: %s\n", value.get()));
   1.403 +
   1.404 +      channel->GetContentType(value);
   1.405 +      LOG(("\tContent-Type: %s\n", value.get()));
   1.406 +
   1.407 +      channel->GetContentCharset(value);
   1.408 +      LOG(("\tContent-Charset: %s\n", value.get()));
   1.409 +
   1.410 +      int64_t length = -1;
   1.411 +      if (NS_SUCCEEDED(channel->GetContentLength(&length))) {
   1.412 +        LOG(("\tContent-Length: %lld\n", length));
   1.413 +      } else {
   1.414 +        LOG(("\tContent-Length: Unknown\n"));
   1.415 +      }
   1.416 +    }
   1.417 +
   1.418 +    nsCOMPtr<nsISupports> owner;
   1.419 +    channel->GetOwner(getter_AddRefs(owner));
   1.420 +    LOG(("\tChannel Owner: %x\n", owner.get()));
   1.421 +  }
   1.422 +
   1.423 +  nsCOMPtr<nsIPropertyBag2> props = do_QueryInterface(request);
   1.424 +  if (props) {
   1.425 +      nsCOMPtr<nsIURI> foo;
   1.426 +      props->GetPropertyAsInterface(NS_LITERAL_STRING("test.foo"),
   1.427 +                                    NS_GET_IID(nsIURI),
   1.428 +                                    getter_AddRefs(foo));
   1.429 +      if (foo) {
   1.430 +          nsAutoCString spec;
   1.431 +          foo->GetSpec(spec);
   1.432 +          LOG(("\ttest.foo: %s\n", spec.get()));
   1.433 +      }
   1.434 +  }
   1.435 +
   1.436 +  nsCOMPtr<nsIHttpChannelInternal> httpChannelInt(do_QueryInterface(request));
   1.437 +  if (httpChannelInt) {
   1.438 +      uint32_t majorVer, minorVer;
   1.439 +      nsresult rv = httpChannelInt->GetResponseVersion(&majorVer, &minorVer);
   1.440 +      if (NS_SUCCEEDED(rv)) {
   1.441 +          LOG(("HTTP Response version: %u.%u\n", majorVer, minorVer));
   1.442 +      }
   1.443 +  }
   1.444 +  nsCOMPtr<nsIHttpChannel> httpChannel(do_QueryInterface(request));
   1.445 +  if (httpChannel) {
   1.446 +    HeaderVisitor *visitor = new HeaderVisitor();
   1.447 +    if (!visitor)
   1.448 +      return NS_ERROR_OUT_OF_MEMORY;
   1.449 +    NS_ADDREF(visitor);
   1.450 +
   1.451 +    LOG(("HTTP request headers:\n"));
   1.452 +    httpChannel->VisitRequestHeaders(visitor);
   1.453 +
   1.454 +    LOG(("HTTP response headers:\n"));
   1.455 +    httpChannel->VisitResponseHeaders(visitor);
   1.456 +
   1.457 +    NS_RELEASE(visitor);
   1.458 +  }
   1.459 +
   1.460 +  nsCOMPtr<nsIResumableChannel> resChannel = do_QueryInterface(request);
   1.461 +  if (resChannel) {
   1.462 +      LOG(("Resumable entity identification:\n"));
   1.463 +      nsAutoCString entityID;
   1.464 +      nsresult rv = resChannel->GetEntityID(entityID);
   1.465 +      if (NS_SUCCEEDED(rv)) {
   1.466 +          LOG(("\t|%s|\n", entityID.get()));
   1.467 +      }
   1.468 +      else {
   1.469 +          LOG(("\t<none>\n"));
   1.470 +      }
   1.471 +  }
   1.472 +
   1.473 +  return NS_OK;
   1.474 +}
   1.475 +
   1.476 +NS_IMETHODIMP
   1.477 +InputTestConsumer::OnDataAvailable(nsIRequest *request, 
   1.478 +                                   nsISupports* context,
   1.479 +                                   nsIInputStream *aIStream, 
   1.480 +                                   uint64_t aSourceOffset,
   1.481 +                                   uint32_t aLength)
   1.482 +{
   1.483 +  char buf[1025];
   1.484 +  uint32_t amt, size;
   1.485 +  nsresult rv;
   1.486 +  URLLoadInfo* info = (URLLoadInfo*)context;
   1.487 +
   1.488 +  while (aLength) {
   1.489 +    size = std::min<uint32_t>(aLength, sizeof(buf));
   1.490 +
   1.491 +    rv = aIStream->Read(buf, size, &amt);
   1.492 +    if (NS_FAILED(rv)) {
   1.493 +      NS_ASSERTION((NS_BASE_STREAM_WOULD_BLOCK != rv), 
   1.494 +                   "The stream should never block.");
   1.495 +      return rv;
   1.496 +    }
   1.497 +    if (gVerbose) {
   1.498 +      buf[amt] = '\0';
   1.499 +      puts(buf);
   1.500 +    }
   1.501 +    if (info) {
   1.502 +      info->mBytesRead += amt;
   1.503 +    }
   1.504 +
   1.505 +    aLength -= amt;
   1.506 +  }
   1.507 +  return NS_OK;
   1.508 +}
   1.509 +
   1.510 +NS_IMETHODIMP
   1.511 +InputTestConsumer::OnStopRequest(nsIRequest *request, nsISupports* context,
   1.512 +                                 nsresult aStatus)
   1.513 +{
   1.514 +  LOG(("InputTestConsumer::OnStopRequest [status=%x]\n", aStatus));
   1.515 +
   1.516 +  URLLoadInfo* info = (URLLoadInfo*)context;
   1.517 +
   1.518 +  if (info) {
   1.519 +    uint32_t httpStatus;
   1.520 +    bool bHTTPURL = false;
   1.521 +
   1.522 +    info->mTotalTime = PR_Now() - info->mTotalTime;
   1.523 +
   1.524 +    double readTime = ((info->mTotalTime-info->mConnectTime)/1000.0)/1000.0;
   1.525 +
   1.526 +    nsCOMPtr<nsIHttpChannel> pHTTPCon(do_QueryInterface(request));
   1.527 +    if (pHTTPCon) {
   1.528 +        pHTTPCon->GetResponseStatus(&httpStatus);
   1.529 +        bHTTPURL = true;
   1.530 +    }
   1.531 +
   1.532 +    LOG(("\nFinished loading: %s  Status Code: %x\n", info->Name(), aStatus));
   1.533 +    if (bHTTPURL) {
   1.534 +      LOG(("\tHTTP Status: %u\n", httpStatus));
   1.535 +    }
   1.536 +    if (NS_ERROR_UNKNOWN_HOST == aStatus ||
   1.537 +        NS_ERROR_UNKNOWN_PROXY_HOST == aStatus) {
   1.538 +      LOG(("\tDNS lookup failed.\n"));
   1.539 +    }
   1.540 +    LOG(("\tTime to connect: %.3f seconds\n", (info->mConnectTime/1000.0)/1000.0));
   1.541 +    LOG(("\tTime to read: %.3f seconds.\n", readTime));
   1.542 +    LOG(("\tRead: %lld bytes.\n", info->mBytesRead));
   1.543 +    if (info->mBytesRead == int64_t(0)) {
   1.544 +    } else if (readTime > 0.0) {
   1.545 +      LOG(("\tThroughput: %.0f bps.\n", (double)(info->mBytesRead*int64_t(8))/readTime));
   1.546 +    } else {
   1.547 +      LOG(("\tThroughput: REAL FAST!!\n"));
   1.548 +    }
   1.549 +
   1.550 +    nsCOMPtr<nsITimedChannel> timed(do_QueryInterface(request));
   1.551 +    if (timed)
   1.552 +        PrintTimingInformation(timed);
   1.553 +  } else {
   1.554 +    LOG(("\nFinished loading: UNKNOWN URL. Status Code: %x\n", aStatus));
   1.555 +  }
   1.556 +
   1.557 +  if (--gKeepRunning == 0)
   1.558 +    QuitPumpingEvents();
   1.559 +  return NS_OK;
   1.560 +}
   1.561 +
   1.562 +//-----------------------------------------------------------------------------
   1.563 +// NotificationCallbacks
   1.564 +//-----------------------------------------------------------------------------
   1.565 +
   1.566 +class NotificationCallbacks MOZ_FINAL : public nsIInterfaceRequestor {
   1.567 +public:
   1.568 +    NS_DECL_ISUPPORTS
   1.569 +
   1.570 +    NotificationCallbacks() {
   1.571 +    }
   1.572 +
   1.573 +    NS_IMETHOD GetInterface(const nsIID& iid, void* *result) {
   1.574 +        nsresult rv = NS_ERROR_FAILURE;
   1.575 +
   1.576 +        if (iid.Equals(NS_GET_IID(nsIChannelEventSink))) {
   1.577 +          TestChannelEventSink *sink;
   1.578 +
   1.579 +          sink = new TestChannelEventSink();
   1.580 +          if (sink == nullptr)
   1.581 +            return NS_ERROR_OUT_OF_MEMORY;
   1.582 +          NS_ADDREF(sink);
   1.583 +          rv = sink->QueryInterface(iid, result);
   1.584 +          NS_RELEASE(sink);
   1.585 +        }
   1.586 +
   1.587 +        if (iid.Equals(NS_GET_IID(nsIAuthPrompt))) {
   1.588 +          TestAuthPrompt *prompt;
   1.589 +
   1.590 +          prompt = new TestAuthPrompt();
   1.591 +          if (prompt == nullptr)
   1.592 +            return NS_ERROR_OUT_OF_MEMORY;
   1.593 +          NS_ADDREF(prompt);
   1.594 +          rv = prompt->QueryInterface(iid, result);
   1.595 +          NS_RELEASE(prompt);
   1.596 +        }
   1.597 +        return rv;
   1.598 +    }
   1.599 +};
   1.600 +
   1.601 +NS_IMPL_ISUPPORTS(NotificationCallbacks, nsIInterfaceRequestor)
   1.602 +
   1.603 +//-----------------------------------------------------------------------------
   1.604 +// helpers...
   1.605 +//-----------------------------------------------------------------------------
   1.606 +
   1.607 +nsresult StartLoadingURL(const char* aUrlString)
   1.608 +{
   1.609 +    nsresult rv;
   1.610 +
   1.611 +    nsCOMPtr<nsIIOService> pService(do_GetService(kIOServiceCID, &rv));
   1.612 +    if (pService) {
   1.613 +        nsCOMPtr<nsIURI> pURL;
   1.614 +
   1.615 +        rv = pService->NewURI(nsDependentCString(aUrlString), nullptr, nullptr, getter_AddRefs(pURL));
   1.616 +        if (NS_FAILED(rv)) {
   1.617 +            LOG(("ERROR: NewURI failed for %s [rv=%x]\n", aUrlString));
   1.618 +            return rv;
   1.619 +        }
   1.620 +        nsCOMPtr<nsIChannel> pChannel;
   1.621 +
   1.622 +        NotificationCallbacks* callbacks = new NotificationCallbacks();
   1.623 +        if (!callbacks) {
   1.624 +            LOG(("Failed to create a new consumer!"));
   1.625 +            return NS_ERROR_OUT_OF_MEMORY;;
   1.626 +        }
   1.627 +        NS_ADDREF(callbacks);
   1.628 +
   1.629 +        // Async reading thru the calls of the event sink interface
   1.630 +        rv = NS_NewChannel(getter_AddRefs(pChannel), pURL, pService,
   1.631 +                           nullptr,     // loadGroup
   1.632 +                           callbacks); // notificationCallbacks
   1.633 +        NS_RELEASE(callbacks);
   1.634 +        if (NS_FAILED(rv)) {
   1.635 +            LOG(("ERROR: NS_OpenURI failed for %s [rv=%x]\n", aUrlString, rv));
   1.636 +            return rv;
   1.637 +        }
   1.638 +
   1.639 +        nsCOMPtr<nsITimedChannel> timed(do_QueryInterface(pChannel));
   1.640 +        if (timed)
   1.641 +            timed->SetTimingEnabled(true);
   1.642 +
   1.643 +        nsCOMPtr<nsIWritablePropertyBag2> props = do_QueryInterface(pChannel);
   1.644 +        if (props) {
   1.645 +            rv = props->SetPropertyAsInterface(NS_LITERAL_STRING("test.foo"),
   1.646 +                                               pURL);
   1.647 +            if (NS_SUCCEEDED(rv)) {
   1.648 +                LOG(("set prop 'test.foo'\n"));
   1.649 +            }
   1.650 +        }
   1.651 +
   1.652 +        /* 
   1.653 +           You may optionally add/set other headers on this
   1.654 +           request object. This is done by QI for the specific
   1.655 +           protocolConnection.
   1.656 +        */
   1.657 +        nsCOMPtr<nsIHttpChannel> pHTTPCon(do_QueryInterface(pChannel));
   1.658 +
   1.659 +        if (pHTTPCon) {
   1.660 +            // Setting a sample header.
   1.661 +            rv = pHTTPCon->SetRequestHeader(NS_LITERAL_CSTRING("sample-header"),
   1.662 +                                            NS_LITERAL_CSTRING("Sample-Value"),
   1.663 +                                            false);
   1.664 +            if (NS_FAILED(rv)) return rv;
   1.665 +        }            
   1.666 +        InputTestConsumer* listener;
   1.667 +
   1.668 +        listener = new InputTestConsumer;
   1.669 +        NS_IF_ADDREF(listener);
   1.670 +        if (!listener) {
   1.671 +            NS_ERROR("Failed to create a new stream listener!");
   1.672 +            return NS_ERROR_OUT_OF_MEMORY;;
   1.673 +        }
   1.674 +
   1.675 +        URLLoadInfo* info;
   1.676 +        info = new URLLoadInfo(aUrlString);
   1.677 +        NS_IF_ADDREF(info);
   1.678 +        if (!info) {
   1.679 +            NS_ERROR("Failed to create a load info!");
   1.680 +            return NS_ERROR_OUT_OF_MEMORY;
   1.681 +        }
   1.682 +
   1.683 +        if (gResume) {
   1.684 +            nsCOMPtr<nsIResumableChannel> res = do_QueryInterface(pChannel);
   1.685 +            if (!res) {
   1.686 +                NS_ERROR("Channel is not resumable!");
   1.687 +                return NS_ERROR_UNEXPECTED;
   1.688 +            }
   1.689 +            nsAutoCString id;
   1.690 +            if (gEntityID)
   1.691 +                id = gEntityID;
   1.692 +            LOG(("* resuming at %llu bytes, with entity id |%s|\n", gStartAt, id.get()));
   1.693 +            res->ResumeAt(gStartAt, id);
   1.694 +        }
   1.695 +        rv = pChannel->AsyncOpen(listener,  // IStreamListener consumer
   1.696 +                                 info);
   1.697 +
   1.698 +        if (NS_SUCCEEDED(rv)) {
   1.699 +            gKeepRunning++;
   1.700 +        }
   1.701 +        else {
   1.702 +            LOG(("ERROR: AsyncOpen failed [rv=%x]\n", rv));
   1.703 +        }
   1.704 +        NS_RELEASE(listener);
   1.705 +        NS_RELEASE(info);
   1.706 +    }
   1.707 +
   1.708 +    return rv;
   1.709 +}
   1.710 +
   1.711 +static int32_t
   1.712 +FindChar(nsCString& buffer, char c)
   1.713 +{
   1.714 +    const char *b;
   1.715 +    int32_t len = NS_CStringGetData(buffer, &b);
   1.716 +
   1.717 +    for (int32_t offset = 0; offset < len; ++offset) {
   1.718 +        if (b[offset] == c)
   1.719 +            return offset;
   1.720 +    }
   1.721 +
   1.722 +    return -1;
   1.723 +}
   1.724 +        
   1.725 +
   1.726 +static void
   1.727 +StripChar(nsCString& buffer, char c)
   1.728 +{
   1.729 +    const char *b;
   1.730 +    uint32_t len = NS_CStringGetData(buffer, &b) - 1;
   1.731 +
   1.732 +    for (; len > 0; --len) {
   1.733 +        if (b[len] == c) {
   1.734 +            buffer.Cut(len, 1);
   1.735 +            NS_CStringGetData(buffer, &b);
   1.736 +        }
   1.737 +    }
   1.738 +}
   1.739 +
   1.740 +nsresult LoadURLsFromFile(char *aFileName)
   1.741 +{
   1.742 +    nsresult rv = NS_OK;
   1.743 +    int32_t len, offset;
   1.744 +    PRFileDesc* fd;
   1.745 +    char buffer[1024];
   1.746 +    nsCString fileBuffer;
   1.747 +    nsCString urlString;
   1.748 +
   1.749 +    fd = PR_Open(aFileName, PR_RDONLY, 777);
   1.750 +    if (!fd) {
   1.751 +        return NS_ERROR_FAILURE;
   1.752 +    }
   1.753 +
   1.754 +    // Keep reading the file until EOF (or an error) is reached...        
   1.755 +    do {
   1.756 +        len = PR_Read(fd, buffer, sizeof(buffer));
   1.757 +        if (len>0) {
   1.758 +            fileBuffer.Append(buffer, len);
   1.759 +            // Treat each line as a URL...
   1.760 +            while ((offset = FindChar(fileBuffer, '\n')) != -1) {
   1.761 +                urlString = StringHead(fileBuffer, offset);
   1.762 +                fileBuffer.Cut(0, offset+1);
   1.763 +
   1.764 +                StripChar(urlString, '\r');
   1.765 +                if (urlString.Length()) {
   1.766 +                    LOG(("\t%s\n", urlString.get()));
   1.767 +                    rv = StartLoadingURL(urlString.get());
   1.768 +                    if (NS_FAILED(rv)) {
   1.769 +                        // No need to log an error -- StartLoadingURL already
   1.770 +                        // did that for us, probably.
   1.771 +                        PR_Close(fd);
   1.772 +                        return rv;
   1.773 +                    }
   1.774 +                }
   1.775 +            }
   1.776 +        }
   1.777 +    } while (len>0);
   1.778 +
   1.779 +    // If anything is left in the fileBuffer, treat it as a URL...
   1.780 +    StripChar(fileBuffer, '\r');
   1.781 +    if (fileBuffer.Length()) {
   1.782 +        LOG(("\t%s\n", fileBuffer.get()));
   1.783 +        StartLoadingURL(fileBuffer.get());
   1.784 +    }
   1.785 +
   1.786 +    PR_Close(fd);
   1.787 +    return NS_OK;
   1.788 +}
   1.789 +
   1.790 +
   1.791 +nsresult LoadURLFromConsole()
   1.792 +{
   1.793 +    char buffer[1024];
   1.794 +    printf("Enter URL (\"q\" to start): ");
   1.795 +    unused << scanf("%s", buffer);
   1.796 +    if (buffer[0]=='q') 
   1.797 +        gAskUserForInput = false;
   1.798 +    else
   1.799 +        StartLoadingURL(buffer);
   1.800 +    return NS_OK;
   1.801 +}
   1.802 +
   1.803 +} // namespace
   1.804 +
   1.805 +using namespace TestProtocols;
   1.806 +
   1.807 +int
   1.808 +main(int argc, char* argv[])
   1.809 +{
   1.810 +    if (test_common_init(&argc, &argv) != 0)
   1.811 +        return -1;
   1.812 +
   1.813 +    nsresult rv= (nsresult)-1;
   1.814 +    if (argc < 2) {
   1.815 +        printf("usage: %s [-verbose] [-file <name>] [-resume <startoffset>"
   1.816 +               "[-entityid <entityid>]] [-proxy <proxy>] [-pac <pacURL>]"
   1.817 +               "[-console] <url> <url> ... \n", argv[0]);
   1.818 +        return -1;
   1.819 +    }
   1.820 +
   1.821 +#if defined(PR_LOGGING)
   1.822 +    gTestLog = PR_NewLogModule("Test");
   1.823 +#endif
   1.824 +
   1.825 +    /* 
   1.826 +      The following code only deals with XPCOM registration stuff. and setting
   1.827 +      up the event queues. Copied from TestSocketIO.cpp
   1.828 +    */
   1.829 +
   1.830 +    rv = NS_InitXPCOM2(nullptr, nullptr, nullptr);
   1.831 +    if (NS_FAILED(rv)) return -1;
   1.832 +
   1.833 +    {
   1.834 +        int i;
   1.835 +        LOG(("Trying to load:\n"));
   1.836 +        for (i=1; i<argc; i++) {
   1.837 +            // Turn on verbose printing...
   1.838 +            if (PL_strcasecmp(argv[i], "-verbose") == 0) {
   1.839 +                gVerbose = true;
   1.840 +                continue;
   1.841 +            }
   1.842 +
   1.843 +            // Turn on netlib tracing...
   1.844 +            if (PL_strcasecmp(argv[i], "-file") == 0) {
   1.845 +                LoadURLsFromFile(argv[++i]);
   1.846 +                continue;
   1.847 +            }
   1.848 +
   1.849 +            if (PL_strcasecmp(argv[i], "-console") == 0) {
   1.850 +                gAskUserForInput = true;
   1.851 +                continue;
   1.852 +            }
   1.853 +
   1.854 +            if (PL_strcasecmp(argv[i], "-resume") == 0) {
   1.855 +                gResume = true;
   1.856 +                PR_sscanf(argv[++i], "%llu", &gStartAt);
   1.857 +                continue;
   1.858 +            }
   1.859 +
   1.860 +            if (PL_strcasecmp(argv[i], "-entityid") == 0) {
   1.861 +                gEntityID = argv[++i];
   1.862 +                continue;
   1.863 +            }
   1.864 +
   1.865 +            if (PL_strcasecmp(argv[i], "-proxy") == 0) {
   1.866 +                SetHttpProxy(argv[++i]);
   1.867 +                continue;
   1.868 +            }
   1.869 +
   1.870 +            if (PL_strcasecmp(argv[i], "-pac") == 0) {
   1.871 +                SetPACFile(argv[++i]);
   1.872 +                continue;
   1.873 +            }
   1.874 +
   1.875 +            LOG(("\t%s\n", argv[i]));
   1.876 +            rv = StartLoadingURL(argv[i]);
   1.877 +        }
   1.878 +        // Enter the message pump to allow the URL load to proceed.
   1.879 +        PumpEvents();
   1.880 +    } // this scopes the nsCOMPtrs
   1.881 +    // no nsCOMPtrs are allowed to be alive when you call NS_ShutdownXPCOM
   1.882 +    NS_ShutdownXPCOM(nullptr);
   1.883 +    return NS_FAILED(rv) ? -1 : 0;
   1.884 +}

mercurial