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 +}