1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/netwerk/test/TestSocketTransport.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,312 @@ 1.4 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.5 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.6 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.7 + 1.8 +#include "TestCommon.h" 1.9 +#include "nsIComponentRegistrar.h" 1.10 +#include "nsPISocketTransportService.h" 1.11 +#include "nsISocketTransport.h" 1.12 +#include "nsIAsyncInputStream.h" 1.13 +#include "nsIAsyncOutputStream.h" 1.14 +#include "nsIProgressEventSink.h" 1.15 +#include "nsIInterfaceRequestor.h" 1.16 +#include "nsIInterfaceRequestorUtils.h" 1.17 +#include "nsIRequest.h" 1.18 +#include "nsIServiceManager.h" 1.19 +#include "nsIComponentManager.h" 1.20 +#include "nsCOMPtr.h" 1.21 +#include "nsMemory.h" 1.22 +#include "nsStringAPI.h" 1.23 +#include "nsIDNSService.h" 1.24 +#include "nsIFileStreams.h" 1.25 +#include "nsIStreamListener.h" 1.26 +#include "nsIFile.h" 1.27 +#include "nsNetUtil.h" 1.28 +#include "nsAutoLock.h" 1.29 +#include "prlog.h" 1.30 + 1.31 +//////////////////////////////////////////////////////////////////////////////// 1.32 + 1.33 +#if defined(PR_LOGGING) 1.34 +// 1.35 +// set NSPR_LOG_MODULES=Test:5 1.36 +// 1.37 +static PRLogModuleInfo *gTestLog = nullptr; 1.38 +#endif 1.39 +#define LOG(args) PR_LOG(gTestLog, PR_LOG_DEBUG, args) 1.40 + 1.41 +//////////////////////////////////////////////////////////////////////////////// 1.42 + 1.43 +static NS_DEFINE_CID(kSocketTransportServiceCID, NS_SOCKETTRANSPORTSERVICE_CID); 1.44 + 1.45 +//////////////////////////////////////////////////////////////////////////////// 1.46 + 1.47 +class MyHandler : public nsIOutputStreamCallback 1.48 + , public nsIInputStreamCallback 1.49 +{ 1.50 +public: 1.51 + NS_DECL_THREADSAFE_ISUPPORTS 1.52 + 1.53 + MyHandler(const char *path, 1.54 + nsIAsyncInputStream *in, 1.55 + nsIAsyncOutputStream *out) 1.56 + : mInput(in) 1.57 + , mOutput(out) 1.58 + , mWriteOffset(0) 1.59 + { 1.60 + mBuf.Assign(NS_LITERAL_CSTRING("GET ")); 1.61 + mBuf.Append(path); 1.62 + mBuf.Append(NS_LITERAL_CSTRING(" HTTP/1.0\r\n\r\n")); 1.63 + } 1.64 + virtual ~MyHandler() {} 1.65 + 1.66 + // called on any thread 1.67 + NS_IMETHOD OnOutputStreamReady(nsIAsyncOutputStream *out) 1.68 + { 1.69 + LOG(("OnOutputStreamReady\n")); 1.70 + 1.71 + nsresult rv; 1.72 + uint32_t n, count = mBuf.Length() - mWriteOffset; 1.73 + 1.74 + rv = out->Write(mBuf.get() + mWriteOffset, count, &n); 1.75 + 1.76 + LOG((" write returned [rv=%x count=%u]\n", rv, n)); 1.77 + 1.78 + if (NS_FAILED(rv) || (n == 0)) { 1.79 + if (rv != NS_BASE_STREAM_WOULD_BLOCK) { 1.80 + LOG((" done writing; starting to read\n")); 1.81 + mInput->AsyncWait(this, 0, 0, nullptr); 1.82 + return NS_OK; 1.83 + } 1.84 + } 1.85 + 1.86 + mWriteOffset += n; 1.87 + 1.88 + return out->AsyncWait(this, 0, 0, nullptr); 1.89 + } 1.90 + 1.91 + // called on any thread 1.92 + NS_IMETHOD OnInputStreamReady(nsIAsyncInputStream *in) 1.93 + { 1.94 + LOG(("OnInputStreamReady\n")); 1.95 + 1.96 + nsresult rv; 1.97 + uint32_t n; 1.98 + char buf[500]; 1.99 + 1.100 + rv = in->Read(buf, sizeof(buf), &n); 1.101 + 1.102 + LOG((" read returned [rv=%x count=%u]\n", rv, n)); 1.103 + 1.104 + if (NS_FAILED(rv) || (n == 0)) { 1.105 + if (rv != NS_BASE_STREAM_WOULD_BLOCK) { 1.106 + QuitPumpingEvents(); 1.107 + return NS_OK; 1.108 + } 1.109 + } 1.110 + 1.111 + return in->AsyncWait(this, 0, 0, nullptr); 1.112 + } 1.113 + 1.114 +private: 1.115 + nsCOMPtr<nsIAsyncInputStream> mInput; 1.116 + nsCOMPtr<nsIAsyncOutputStream> mOutput; 1.117 + nsCString mBuf; 1.118 + uint32_t mWriteOffset; 1.119 +}; 1.120 + 1.121 +NS_IMPL_ISUPPORTS(MyHandler, 1.122 + nsIOutputStreamCallback, 1.123 + nsIInputStreamCallback) 1.124 + 1.125 +//////////////////////////////////////////////////////////////////////////////// 1.126 + 1.127 +/** 1.128 + * create transport, open streams, and close 1.129 + */ 1.130 +static nsresult 1.131 +RunCloseTest(nsISocketTransportService *sts, 1.132 + const char *host, int port, 1.133 + uint32_t inFlags, uint32_t outFlags) 1.134 +{ 1.135 + nsresult rv; 1.136 + 1.137 + LOG(("RunCloseTest\n")); 1.138 + 1.139 + nsCOMPtr<nsISocketTransport> transport; 1.140 + rv = sts->CreateTransport(nullptr, 0, 1.141 + nsDependentCString(host), port, nullptr, 1.142 + getter_AddRefs(transport)); 1.143 + if (NS_FAILED(rv)) return rv; 1.144 + 1.145 + nsCOMPtr<nsIInputStream> in; 1.146 + rv = transport->OpenInputStream(inFlags, 0, 0, getter_AddRefs(in)); 1.147 + nsCOMPtr<nsIAsyncInputStream> asyncIn = do_QueryInterface(in, &rv); 1.148 + if (NS_FAILED(rv)) return rv; 1.149 + 1.150 + nsCOMPtr<nsIOutputStream> out; 1.151 + rv = transport->OpenOutputStream(outFlags, 0, 0, getter_AddRefs(out)); 1.152 + nsCOMPtr<nsIAsyncOutputStream> asyncOut = do_QueryInterface(out, &rv); 1.153 + if (NS_FAILED(rv)) return rv; 1.154 + 1.155 + LOG(("waiting 1 second before closing transport and streams...\n")); 1.156 + PR_Sleep(PR_SecondsToInterval(1)); 1.157 + 1.158 + // let nsCOMPtr destructors close everything... 1.159 + return NS_OK; 1.160 +} 1.161 + 1.162 + 1.163 +/** 1.164 + * asynchronously read socket stream 1.165 + */ 1.166 +static nsresult 1.167 +RunTest(nsISocketTransportService *sts, 1.168 + const char *host, int port, const char *path, 1.169 + uint32_t inFlags, uint32_t outFlags) 1.170 +{ 1.171 + nsresult rv; 1.172 + 1.173 + LOG(("RunTest\n")); 1.174 + 1.175 + nsCOMPtr<nsISocketTransport> transport; 1.176 + rv = sts->CreateTransport(nullptr, 0, 1.177 + nsDependentCString(host), port, nullptr, 1.178 + getter_AddRefs(transport)); 1.179 + if (NS_FAILED(rv)) return rv; 1.180 + 1.181 + nsCOMPtr<nsIInputStream> in; 1.182 + rv = transport->OpenInputStream(inFlags, 0, 0, getter_AddRefs(in)); 1.183 + nsCOMPtr<nsIAsyncInputStream> asyncIn = do_QueryInterface(in, &rv); 1.184 + if (NS_FAILED(rv)) return rv; 1.185 + 1.186 + nsCOMPtr<nsIOutputStream> out; 1.187 + rv = transport->OpenOutputStream(outFlags, 0, 0, getter_AddRefs(out)); 1.188 + nsCOMPtr<nsIAsyncOutputStream> asyncOut = do_QueryInterface(out, &rv); 1.189 + if (NS_FAILED(rv)) return rv; 1.190 + 1.191 + MyHandler *handler = new MyHandler(path, asyncIn, asyncOut); 1.192 + if (handler == nullptr) 1.193 + return NS_ERROR_OUT_OF_MEMORY; 1.194 + NS_ADDREF(handler); 1.195 + 1.196 + rv = asyncOut->AsyncWait(handler, 0, 0, nullptr); 1.197 + 1.198 + if (NS_SUCCEEDED(rv)) 1.199 + PumpEvents(); 1.200 + 1.201 + NS_RELEASE(handler); 1.202 + 1.203 + return NS_OK; 1.204 +} 1.205 + 1.206 +//////////////////////////////////////////////////////////////////////////////// 1.207 + 1.208 +int 1.209 +main(int argc, char* argv[]) 1.210 +{ 1.211 + if (test_common_init(&argc, &argv) != 0) 1.212 + return -1; 1.213 + 1.214 + nsresult rv; 1.215 + 1.216 + if (argc < 4) { 1.217 + printf("usage: TestSocketTransport <host> <port> <path>\n"); 1.218 + return -1; 1.219 + } 1.220 + 1.221 + { 1.222 + nsCOMPtr<nsIServiceManager> servMan; 1.223 + NS_InitXPCOM2(getter_AddRefs(servMan), nullptr, nullptr); 1.224 + nsCOMPtr<nsIComponentRegistrar> registrar = do_QueryInterface(servMan); 1.225 + NS_ASSERTION(registrar, "Null nsIComponentRegistrar"); 1.226 + if (registrar) 1.227 + registrar->AutoRegister(nullptr); 1.228 + 1.229 +#if defined(PR_LOGGING) 1.230 + gTestLog = PR_NewLogModule("Test"); 1.231 +#endif 1.232 + 1.233 + // Make sure the DNS service is initialized on the main thread 1.234 + nsCOMPtr<nsIDNSService> dns = 1.235 + do_GetService(NS_DNSSERVICE_CONTRACTID, &rv); 1.236 + if (NS_FAILED(rv)) return rv; 1.237 + 1.238 + nsCOMPtr<nsPISocketTransportService> sts = 1.239 + do_GetService(kSocketTransportServiceCID, &rv); 1.240 + if (NS_FAILED(rv)) return rv; 1.241 + 1.242 + LOG(("phase 1 tests...\n")); 1.243 + 1.244 + LOG(("flags = { OPEN_UNBUFFERED, OPEN_UNBUFFERED }\n")); 1.245 + rv = RunCloseTest(sts, argv[1], atoi(argv[2]), 1.246 + nsITransport::OPEN_UNBUFFERED, 1.247 + nsITransport::OPEN_UNBUFFERED); 1.248 + NS_ASSERTION(NS_SUCCEEDED(rv), "RunCloseTest failed"); 1.249 + 1.250 + LOG(("flags = { OPEN_BUFFERED, OPEN_UNBUFFERED }\n")); 1.251 + rv = RunCloseTest(sts, argv[1], atoi(argv[2]), 1.252 + 0 /* nsITransport::OPEN_BUFFERED */, 1.253 + nsITransport::OPEN_UNBUFFERED); 1.254 + NS_ASSERTION(NS_SUCCEEDED(rv), "RunCloseTest failed"); 1.255 + 1.256 + LOG(("flags = { OPEN_UNBUFFERED, OPEN_BUFFERED }\n")); 1.257 + rv = RunCloseTest(sts, argv[1], atoi(argv[2]), 1.258 + nsITransport::OPEN_UNBUFFERED, 1.259 + 0 /*nsITransport::OPEN_BUFFERED */); 1.260 + NS_ASSERTION(NS_SUCCEEDED(rv), "RunCloseTest failed"); 1.261 + 1.262 + LOG(("flags = { OPEN_BUFFERED, OPEN_BUFFERED }\n")); 1.263 + rv = RunCloseTest(sts, argv[1], atoi(argv[2]), 1.264 + 0 /*nsITransport::OPEN_BUFFERED */, 1.265 + 0 /*nsITransport::OPEN_BUFFERED */); 1.266 + NS_ASSERTION(NS_SUCCEEDED(rv), "RunCloseTest failed"); 1.267 + 1.268 + LOG(("calling Shutdown on socket transport service:\n")); 1.269 + sts->Shutdown(); 1.270 + 1.271 + LOG(("calling Init on socket transport service:\n")); 1.272 + sts->Init(); 1.273 + 1.274 + LOG(("phase 2 tests...\n")); 1.275 + 1.276 + LOG(("flags = { OPEN_UNBUFFERED, OPEN_UNBUFFERED }\n")); 1.277 + rv = RunTest(sts, argv[1], atoi(argv[2]), argv[3], 1.278 + nsITransport::OPEN_UNBUFFERED, 1.279 + nsITransport::OPEN_UNBUFFERED); 1.280 + NS_ASSERTION(NS_SUCCEEDED(rv), "RunTest failed"); 1.281 + 1.282 + LOG(("flags = { OPEN_BUFFERED, OPEN_UNBUFFERED }\n")); 1.283 + rv = RunTest(sts, argv[1], atoi(argv[2]), argv[3], 1.284 + 0 /* nsITransport::OPEN_BUFFERED */, 1.285 + nsITransport::OPEN_UNBUFFERED); 1.286 + NS_ASSERTION(NS_SUCCEEDED(rv), "RunTest failed"); 1.287 + 1.288 + LOG(("flags = { OPEN_UNBUFFERED, OPEN_BUFFERED }\n")); 1.289 + rv = RunTest(sts, argv[1], atoi(argv[2]), argv[3], 1.290 + nsITransport::OPEN_UNBUFFERED, 1.291 + 0 /*nsITransport::OPEN_BUFFERED */); 1.292 + NS_ASSERTION(NS_SUCCEEDED(rv), "RunTest failed"); 1.293 + 1.294 + LOG(("flags = { OPEN_BUFFERED, OPEN_BUFFERED }\n")); 1.295 + rv = RunTest(sts, argv[1], atoi(argv[2]), argv[3], 1.296 + 0 /*nsITransport::OPEN_BUFFERED */, 1.297 + 0 /*nsITransport::OPEN_BUFFERED */); 1.298 + NS_ASSERTION(NS_SUCCEEDED(rv), "RunTest failed"); 1.299 + 1.300 + LOG(("waiting 1 second before calling Shutdown...\n")); 1.301 + PR_Sleep(PR_SecondsToInterval(1)); 1.302 + 1.303 + LOG(("calling Shutdown on socket transport service:\n")); 1.304 + sts->Shutdown(); 1.305 + 1.306 + // give background threads a chance to finish whatever work they may 1.307 + // be doing. 1.308 + LOG(("waiting 1 second before exiting...\n")); 1.309 + PR_Sleep(PR_SecondsToInterval(1)); 1.310 + } // this scopes the nsCOMPtrs 1.311 + // no nsCOMPtrs are allowed to be alive when you call NS_ShutdownXPCOM 1.312 + rv = NS_ShutdownXPCOM(nullptr); 1.313 + NS_ASSERTION(NS_SUCCEEDED(rv), "NS_ShutdownXPCOM failed"); 1.314 + return 0; 1.315 +}