netwerk/test/TestSocketTransport.cpp

Wed, 31 Dec 2014 06:55:46 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:55:46 +0100
changeset 1
ca08bd8f51b2
permissions
-rw-r--r--

Added tag TORBROWSER_REPLICA for changeset 6474c204b198

michael@0 1 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 2 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 4
michael@0 5 #include "TestCommon.h"
michael@0 6 #include "nsIComponentRegistrar.h"
michael@0 7 #include "nsPISocketTransportService.h"
michael@0 8 #include "nsISocketTransport.h"
michael@0 9 #include "nsIAsyncInputStream.h"
michael@0 10 #include "nsIAsyncOutputStream.h"
michael@0 11 #include "nsIProgressEventSink.h"
michael@0 12 #include "nsIInterfaceRequestor.h"
michael@0 13 #include "nsIInterfaceRequestorUtils.h"
michael@0 14 #include "nsIRequest.h"
michael@0 15 #include "nsIServiceManager.h"
michael@0 16 #include "nsIComponentManager.h"
michael@0 17 #include "nsCOMPtr.h"
michael@0 18 #include "nsMemory.h"
michael@0 19 #include "nsStringAPI.h"
michael@0 20 #include "nsIDNSService.h"
michael@0 21 #include "nsIFileStreams.h"
michael@0 22 #include "nsIStreamListener.h"
michael@0 23 #include "nsIFile.h"
michael@0 24 #include "nsNetUtil.h"
michael@0 25 #include "nsAutoLock.h"
michael@0 26 #include "prlog.h"
michael@0 27
michael@0 28 ////////////////////////////////////////////////////////////////////////////////
michael@0 29
michael@0 30 #if defined(PR_LOGGING)
michael@0 31 //
michael@0 32 // set NSPR_LOG_MODULES=Test:5
michael@0 33 //
michael@0 34 static PRLogModuleInfo *gTestLog = nullptr;
michael@0 35 #endif
michael@0 36 #define LOG(args) PR_LOG(gTestLog, PR_LOG_DEBUG, args)
michael@0 37
michael@0 38 ////////////////////////////////////////////////////////////////////////////////
michael@0 39
michael@0 40 static NS_DEFINE_CID(kSocketTransportServiceCID, NS_SOCKETTRANSPORTSERVICE_CID);
michael@0 41
michael@0 42 ////////////////////////////////////////////////////////////////////////////////
michael@0 43
michael@0 44 class MyHandler : public nsIOutputStreamCallback
michael@0 45 , public nsIInputStreamCallback
michael@0 46 {
michael@0 47 public:
michael@0 48 NS_DECL_THREADSAFE_ISUPPORTS
michael@0 49
michael@0 50 MyHandler(const char *path,
michael@0 51 nsIAsyncInputStream *in,
michael@0 52 nsIAsyncOutputStream *out)
michael@0 53 : mInput(in)
michael@0 54 , mOutput(out)
michael@0 55 , mWriteOffset(0)
michael@0 56 {
michael@0 57 mBuf.Assign(NS_LITERAL_CSTRING("GET "));
michael@0 58 mBuf.Append(path);
michael@0 59 mBuf.Append(NS_LITERAL_CSTRING(" HTTP/1.0\r\n\r\n"));
michael@0 60 }
michael@0 61 virtual ~MyHandler() {}
michael@0 62
michael@0 63 // called on any thread
michael@0 64 NS_IMETHOD OnOutputStreamReady(nsIAsyncOutputStream *out)
michael@0 65 {
michael@0 66 LOG(("OnOutputStreamReady\n"));
michael@0 67
michael@0 68 nsresult rv;
michael@0 69 uint32_t n, count = mBuf.Length() - mWriteOffset;
michael@0 70
michael@0 71 rv = out->Write(mBuf.get() + mWriteOffset, count, &n);
michael@0 72
michael@0 73 LOG((" write returned [rv=%x count=%u]\n", rv, n));
michael@0 74
michael@0 75 if (NS_FAILED(rv) || (n == 0)) {
michael@0 76 if (rv != NS_BASE_STREAM_WOULD_BLOCK) {
michael@0 77 LOG((" done writing; starting to read\n"));
michael@0 78 mInput->AsyncWait(this, 0, 0, nullptr);
michael@0 79 return NS_OK;
michael@0 80 }
michael@0 81 }
michael@0 82
michael@0 83 mWriteOffset += n;
michael@0 84
michael@0 85 return out->AsyncWait(this, 0, 0, nullptr);
michael@0 86 }
michael@0 87
michael@0 88 // called on any thread
michael@0 89 NS_IMETHOD OnInputStreamReady(nsIAsyncInputStream *in)
michael@0 90 {
michael@0 91 LOG(("OnInputStreamReady\n"));
michael@0 92
michael@0 93 nsresult rv;
michael@0 94 uint32_t n;
michael@0 95 char buf[500];
michael@0 96
michael@0 97 rv = in->Read(buf, sizeof(buf), &n);
michael@0 98
michael@0 99 LOG((" read returned [rv=%x count=%u]\n", rv, n));
michael@0 100
michael@0 101 if (NS_FAILED(rv) || (n == 0)) {
michael@0 102 if (rv != NS_BASE_STREAM_WOULD_BLOCK) {
michael@0 103 QuitPumpingEvents();
michael@0 104 return NS_OK;
michael@0 105 }
michael@0 106 }
michael@0 107
michael@0 108 return in->AsyncWait(this, 0, 0, nullptr);
michael@0 109 }
michael@0 110
michael@0 111 private:
michael@0 112 nsCOMPtr<nsIAsyncInputStream> mInput;
michael@0 113 nsCOMPtr<nsIAsyncOutputStream> mOutput;
michael@0 114 nsCString mBuf;
michael@0 115 uint32_t mWriteOffset;
michael@0 116 };
michael@0 117
michael@0 118 NS_IMPL_ISUPPORTS(MyHandler,
michael@0 119 nsIOutputStreamCallback,
michael@0 120 nsIInputStreamCallback)
michael@0 121
michael@0 122 ////////////////////////////////////////////////////////////////////////////////
michael@0 123
michael@0 124 /**
michael@0 125 * create transport, open streams, and close
michael@0 126 */
michael@0 127 static nsresult
michael@0 128 RunCloseTest(nsISocketTransportService *sts,
michael@0 129 const char *host, int port,
michael@0 130 uint32_t inFlags, uint32_t outFlags)
michael@0 131 {
michael@0 132 nsresult rv;
michael@0 133
michael@0 134 LOG(("RunCloseTest\n"));
michael@0 135
michael@0 136 nsCOMPtr<nsISocketTransport> transport;
michael@0 137 rv = sts->CreateTransport(nullptr, 0,
michael@0 138 nsDependentCString(host), port, nullptr,
michael@0 139 getter_AddRefs(transport));
michael@0 140 if (NS_FAILED(rv)) return rv;
michael@0 141
michael@0 142 nsCOMPtr<nsIInputStream> in;
michael@0 143 rv = transport->OpenInputStream(inFlags, 0, 0, getter_AddRefs(in));
michael@0 144 nsCOMPtr<nsIAsyncInputStream> asyncIn = do_QueryInterface(in, &rv);
michael@0 145 if (NS_FAILED(rv)) return rv;
michael@0 146
michael@0 147 nsCOMPtr<nsIOutputStream> out;
michael@0 148 rv = transport->OpenOutputStream(outFlags, 0, 0, getter_AddRefs(out));
michael@0 149 nsCOMPtr<nsIAsyncOutputStream> asyncOut = do_QueryInterface(out, &rv);
michael@0 150 if (NS_FAILED(rv)) return rv;
michael@0 151
michael@0 152 LOG(("waiting 1 second before closing transport and streams...\n"));
michael@0 153 PR_Sleep(PR_SecondsToInterval(1));
michael@0 154
michael@0 155 // let nsCOMPtr destructors close everything...
michael@0 156 return NS_OK;
michael@0 157 }
michael@0 158
michael@0 159
michael@0 160 /**
michael@0 161 * asynchronously read socket stream
michael@0 162 */
michael@0 163 static nsresult
michael@0 164 RunTest(nsISocketTransportService *sts,
michael@0 165 const char *host, int port, const char *path,
michael@0 166 uint32_t inFlags, uint32_t outFlags)
michael@0 167 {
michael@0 168 nsresult rv;
michael@0 169
michael@0 170 LOG(("RunTest\n"));
michael@0 171
michael@0 172 nsCOMPtr<nsISocketTransport> transport;
michael@0 173 rv = sts->CreateTransport(nullptr, 0,
michael@0 174 nsDependentCString(host), port, nullptr,
michael@0 175 getter_AddRefs(transport));
michael@0 176 if (NS_FAILED(rv)) return rv;
michael@0 177
michael@0 178 nsCOMPtr<nsIInputStream> in;
michael@0 179 rv = transport->OpenInputStream(inFlags, 0, 0, getter_AddRefs(in));
michael@0 180 nsCOMPtr<nsIAsyncInputStream> asyncIn = do_QueryInterface(in, &rv);
michael@0 181 if (NS_FAILED(rv)) return rv;
michael@0 182
michael@0 183 nsCOMPtr<nsIOutputStream> out;
michael@0 184 rv = transport->OpenOutputStream(outFlags, 0, 0, getter_AddRefs(out));
michael@0 185 nsCOMPtr<nsIAsyncOutputStream> asyncOut = do_QueryInterface(out, &rv);
michael@0 186 if (NS_FAILED(rv)) return rv;
michael@0 187
michael@0 188 MyHandler *handler = new MyHandler(path, asyncIn, asyncOut);
michael@0 189 if (handler == nullptr)
michael@0 190 return NS_ERROR_OUT_OF_MEMORY;
michael@0 191 NS_ADDREF(handler);
michael@0 192
michael@0 193 rv = asyncOut->AsyncWait(handler, 0, 0, nullptr);
michael@0 194
michael@0 195 if (NS_SUCCEEDED(rv))
michael@0 196 PumpEvents();
michael@0 197
michael@0 198 NS_RELEASE(handler);
michael@0 199
michael@0 200 return NS_OK;
michael@0 201 }
michael@0 202
michael@0 203 ////////////////////////////////////////////////////////////////////////////////
michael@0 204
michael@0 205 int
michael@0 206 main(int argc, char* argv[])
michael@0 207 {
michael@0 208 if (test_common_init(&argc, &argv) != 0)
michael@0 209 return -1;
michael@0 210
michael@0 211 nsresult rv;
michael@0 212
michael@0 213 if (argc < 4) {
michael@0 214 printf("usage: TestSocketTransport <host> <port> <path>\n");
michael@0 215 return -1;
michael@0 216 }
michael@0 217
michael@0 218 {
michael@0 219 nsCOMPtr<nsIServiceManager> servMan;
michael@0 220 NS_InitXPCOM2(getter_AddRefs(servMan), nullptr, nullptr);
michael@0 221 nsCOMPtr<nsIComponentRegistrar> registrar = do_QueryInterface(servMan);
michael@0 222 NS_ASSERTION(registrar, "Null nsIComponentRegistrar");
michael@0 223 if (registrar)
michael@0 224 registrar->AutoRegister(nullptr);
michael@0 225
michael@0 226 #if defined(PR_LOGGING)
michael@0 227 gTestLog = PR_NewLogModule("Test");
michael@0 228 #endif
michael@0 229
michael@0 230 // Make sure the DNS service is initialized on the main thread
michael@0 231 nsCOMPtr<nsIDNSService> dns =
michael@0 232 do_GetService(NS_DNSSERVICE_CONTRACTID, &rv);
michael@0 233 if (NS_FAILED(rv)) return rv;
michael@0 234
michael@0 235 nsCOMPtr<nsPISocketTransportService> sts =
michael@0 236 do_GetService(kSocketTransportServiceCID, &rv);
michael@0 237 if (NS_FAILED(rv)) return rv;
michael@0 238
michael@0 239 LOG(("phase 1 tests...\n"));
michael@0 240
michael@0 241 LOG(("flags = { OPEN_UNBUFFERED, OPEN_UNBUFFERED }\n"));
michael@0 242 rv = RunCloseTest(sts, argv[1], atoi(argv[2]),
michael@0 243 nsITransport::OPEN_UNBUFFERED,
michael@0 244 nsITransport::OPEN_UNBUFFERED);
michael@0 245 NS_ASSERTION(NS_SUCCEEDED(rv), "RunCloseTest failed");
michael@0 246
michael@0 247 LOG(("flags = { OPEN_BUFFERED, OPEN_UNBUFFERED }\n"));
michael@0 248 rv = RunCloseTest(sts, argv[1], atoi(argv[2]),
michael@0 249 0 /* nsITransport::OPEN_BUFFERED */,
michael@0 250 nsITransport::OPEN_UNBUFFERED);
michael@0 251 NS_ASSERTION(NS_SUCCEEDED(rv), "RunCloseTest failed");
michael@0 252
michael@0 253 LOG(("flags = { OPEN_UNBUFFERED, OPEN_BUFFERED }\n"));
michael@0 254 rv = RunCloseTest(sts, argv[1], atoi(argv[2]),
michael@0 255 nsITransport::OPEN_UNBUFFERED,
michael@0 256 0 /*nsITransport::OPEN_BUFFERED */);
michael@0 257 NS_ASSERTION(NS_SUCCEEDED(rv), "RunCloseTest failed");
michael@0 258
michael@0 259 LOG(("flags = { OPEN_BUFFERED, OPEN_BUFFERED }\n"));
michael@0 260 rv = RunCloseTest(sts, argv[1], atoi(argv[2]),
michael@0 261 0 /*nsITransport::OPEN_BUFFERED */,
michael@0 262 0 /*nsITransport::OPEN_BUFFERED */);
michael@0 263 NS_ASSERTION(NS_SUCCEEDED(rv), "RunCloseTest failed");
michael@0 264
michael@0 265 LOG(("calling Shutdown on socket transport service:\n"));
michael@0 266 sts->Shutdown();
michael@0 267
michael@0 268 LOG(("calling Init on socket transport service:\n"));
michael@0 269 sts->Init();
michael@0 270
michael@0 271 LOG(("phase 2 tests...\n"));
michael@0 272
michael@0 273 LOG(("flags = { OPEN_UNBUFFERED, OPEN_UNBUFFERED }\n"));
michael@0 274 rv = RunTest(sts, argv[1], atoi(argv[2]), argv[3],
michael@0 275 nsITransport::OPEN_UNBUFFERED,
michael@0 276 nsITransport::OPEN_UNBUFFERED);
michael@0 277 NS_ASSERTION(NS_SUCCEEDED(rv), "RunTest failed");
michael@0 278
michael@0 279 LOG(("flags = { OPEN_BUFFERED, OPEN_UNBUFFERED }\n"));
michael@0 280 rv = RunTest(sts, argv[1], atoi(argv[2]), argv[3],
michael@0 281 0 /* nsITransport::OPEN_BUFFERED */,
michael@0 282 nsITransport::OPEN_UNBUFFERED);
michael@0 283 NS_ASSERTION(NS_SUCCEEDED(rv), "RunTest failed");
michael@0 284
michael@0 285 LOG(("flags = { OPEN_UNBUFFERED, OPEN_BUFFERED }\n"));
michael@0 286 rv = RunTest(sts, argv[1], atoi(argv[2]), argv[3],
michael@0 287 nsITransport::OPEN_UNBUFFERED,
michael@0 288 0 /*nsITransport::OPEN_BUFFERED */);
michael@0 289 NS_ASSERTION(NS_SUCCEEDED(rv), "RunTest failed");
michael@0 290
michael@0 291 LOG(("flags = { OPEN_BUFFERED, OPEN_BUFFERED }\n"));
michael@0 292 rv = RunTest(sts, argv[1], atoi(argv[2]), argv[3],
michael@0 293 0 /*nsITransport::OPEN_BUFFERED */,
michael@0 294 0 /*nsITransport::OPEN_BUFFERED */);
michael@0 295 NS_ASSERTION(NS_SUCCEEDED(rv), "RunTest failed");
michael@0 296
michael@0 297 LOG(("waiting 1 second before calling Shutdown...\n"));
michael@0 298 PR_Sleep(PR_SecondsToInterval(1));
michael@0 299
michael@0 300 LOG(("calling Shutdown on socket transport service:\n"));
michael@0 301 sts->Shutdown();
michael@0 302
michael@0 303 // give background threads a chance to finish whatever work they may
michael@0 304 // be doing.
michael@0 305 LOG(("waiting 1 second before exiting...\n"));
michael@0 306 PR_Sleep(PR_SecondsToInterval(1));
michael@0 307 } // this scopes the nsCOMPtrs
michael@0 308 // no nsCOMPtrs are allowed to be alive when you call NS_ShutdownXPCOM
michael@0 309 rv = NS_ShutdownXPCOM(nullptr);
michael@0 310 NS_ASSERTION(NS_SUCCEEDED(rv), "NS_ShutdownXPCOM failed");
michael@0 311 return 0;
michael@0 312 }

mercurial