1 /* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 #include "TestCommon.h"
6 #include "nsIComponentRegistrar.h"
7 #include "nsPISocketTransportService.h"
8 #include "nsISocketTransport.h"
9 #include "nsIAsyncInputStream.h"
10 #include "nsIAsyncOutputStream.h"
11 #include "nsIProgressEventSink.h"
12 #include "nsIInterfaceRequestor.h"
13 #include "nsIInterfaceRequestorUtils.h"
14 #include "nsIRequest.h"
15 #include "nsIServiceManager.h"
16 #include "nsIComponentManager.h"
19 #include "nsStringAPI.h"
20 #include "nsIDNSService.h"
21 #include "nsIFileStreams.h"
22 #include "nsIStreamListener.h"
24 #include "nsNetUtil.h"
25 #include "nsAutoLock.h"
28 ////////////////////////////////////////////////////////////////////////////////
30 #if defined(PR_LOGGING)
32 // set NSPR_LOG_MODULES=Test:5
34 static PRLogModuleInfo
*gTestLog
= nullptr;
36 #define LOG(args) PR_LOG(gTestLog, PR_LOG_DEBUG, args)
38 ////////////////////////////////////////////////////////////////////////////////
40 static NS_DEFINE_CID(kSocketTransportServiceCID
, NS_SOCKETTRANSPORTSERVICE_CID
);
42 ////////////////////////////////////////////////////////////////////////////////
44 class MyHandler
: public nsIOutputStreamCallback
45 , public nsIInputStreamCallback
48 NS_DECL_THREADSAFE_ISUPPORTS
50 MyHandler(const char *path
,
51 nsIAsyncInputStream
*in
,
52 nsIAsyncOutputStream
*out
)
57 mBuf
.AssignLiteral("GET ");
59 mBuf
.AppendLiteral(" HTTP/1.0\r\n\r\n");
61 virtual ~MyHandler() {}
63 // called on any thread
64 NS_IMETHOD
OnOutputStreamReady(nsIAsyncOutputStream
*out
)
66 LOG(("OnOutputStreamReady\n"));
69 uint32_t n
, count
= mBuf
.Length() - mWriteOffset
;
71 rv
= out
->Write(mBuf
.get() + mWriteOffset
, count
, &n
);
73 LOG((" write returned [rv=%x count=%u]\n", rv
, n
));
75 if (NS_FAILED(rv
) || (n
== 0)) {
76 if (rv
!= NS_BASE_STREAM_WOULD_BLOCK
) {
77 LOG((" done writing; starting to read\n"));
78 mInput
->AsyncWait(this, 0, 0, nullptr);
85 return out
->AsyncWait(this, 0, 0, nullptr);
88 // called on any thread
89 NS_IMETHOD
OnInputStreamReady(nsIAsyncInputStream
*in
)
91 LOG(("OnInputStreamReady\n"));
97 rv
= in
->Read(buf
, sizeof(buf
), &n
);
99 LOG((" read returned [rv=%x count=%u]\n", rv
, n
));
101 if (NS_FAILED(rv
) || (n
== 0)) {
102 if (rv
!= NS_BASE_STREAM_WOULD_BLOCK
) {
108 return in
->AsyncWait(this, 0, 0, nullptr);
112 nsCOMPtr
<nsIAsyncInputStream
> mInput
;
113 nsCOMPtr
<nsIAsyncOutputStream
> mOutput
;
115 uint32_t mWriteOffset
;
118 NS_IMPL_ISUPPORTS(MyHandler
,
119 nsIOutputStreamCallback
,
120 nsIInputStreamCallback
)
122 ////////////////////////////////////////////////////////////////////////////////
125 * create transport, open streams, and close
128 RunCloseTest(nsISocketTransportService
*sts
,
129 const char *host
, int port
,
130 uint32_t inFlags
, uint32_t outFlags
)
134 LOG(("RunCloseTest\n"));
136 nsCOMPtr
<nsISocketTransport
> transport
;
137 rv
= sts
->CreateTransport(nullptr, 0,
138 nsDependentCString(host
), port
, nullptr,
139 getter_AddRefs(transport
));
140 if (NS_FAILED(rv
)) return rv
;
142 nsCOMPtr
<nsIInputStream
> in
;
143 rv
= transport
->OpenInputStream(inFlags
, 0, 0, getter_AddRefs(in
));
144 nsCOMPtr
<nsIAsyncInputStream
> asyncIn
= do_QueryInterface(in
, &rv
);
145 if (NS_FAILED(rv
)) return rv
;
147 nsCOMPtr
<nsIOutputStream
> out
;
148 rv
= transport
->OpenOutputStream(outFlags
, 0, 0, getter_AddRefs(out
));
149 nsCOMPtr
<nsIAsyncOutputStream
> asyncOut
= do_QueryInterface(out
, &rv
);
150 if (NS_FAILED(rv
)) return rv
;
152 LOG(("waiting 1 second before closing transport and streams...\n"));
153 PR_Sleep(PR_SecondsToInterval(1));
155 // let nsCOMPtr destructors close everything...
161 * asynchronously read socket stream
164 RunTest(nsISocketTransportService
*sts
,
165 const char *host
, int port
, const char *path
,
166 uint32_t inFlags
, uint32_t outFlags
)
172 nsCOMPtr
<nsISocketTransport
> transport
;
173 rv
= sts
->CreateTransport(nullptr, 0,
174 nsDependentCString(host
), port
, nullptr,
175 getter_AddRefs(transport
));
176 if (NS_FAILED(rv
)) return rv
;
178 nsCOMPtr
<nsIInputStream
> in
;
179 rv
= transport
->OpenInputStream(inFlags
, 0, 0, getter_AddRefs(in
));
180 nsCOMPtr
<nsIAsyncInputStream
> asyncIn
= do_QueryInterface(in
, &rv
);
181 if (NS_FAILED(rv
)) return rv
;
183 nsCOMPtr
<nsIOutputStream
> out
;
184 rv
= transport
->OpenOutputStream(outFlags
, 0, 0, getter_AddRefs(out
));
185 nsCOMPtr
<nsIAsyncOutputStream
> asyncOut
= do_QueryInterface(out
, &rv
);
186 if (NS_FAILED(rv
)) return rv
;
188 MyHandler
*handler
= new MyHandler(path
, asyncIn
, asyncOut
);
189 if (handler
== nullptr)
190 return NS_ERROR_OUT_OF_MEMORY
;
193 rv
= asyncOut
->AsyncWait(handler
, 0, 0, nullptr);
195 if (NS_SUCCEEDED(rv
))
203 ////////////////////////////////////////////////////////////////////////////////
206 main(int argc
, char* argv
[])
208 if (test_common_init(&argc
, &argv
) != 0)
214 printf("usage: TestSocketTransport <host> <port> <path>\n");
219 nsCOMPtr
<nsIServiceManager
> servMan
;
220 NS_InitXPCOM2(getter_AddRefs(servMan
), nullptr, nullptr);
221 nsCOMPtr
<nsIComponentRegistrar
> registrar
= do_QueryInterface(servMan
);
222 NS_ASSERTION(registrar
, "Null nsIComponentRegistrar");
224 registrar
->AutoRegister(nullptr);
226 #if defined(PR_LOGGING)
227 gTestLog
= PR_NewLogModule("Test");
230 // Make sure the DNS service is initialized on the main thread
231 nsCOMPtr
<nsIDNSService
> dns
=
232 do_GetService(NS_DNSSERVICE_CONTRACTID
, &rv
);
233 if (NS_FAILED(rv
)) return rv
;
235 nsCOMPtr
<nsPISocketTransportService
> sts
=
236 do_GetService(kSocketTransportServiceCID
, &rv
);
237 if (NS_FAILED(rv
)) return rv
;
239 LOG(("phase 1 tests...\n"));
241 LOG(("flags = { OPEN_UNBUFFERED, OPEN_UNBUFFERED }\n"));
242 rv
= RunCloseTest(sts
, argv
[1], atoi(argv
[2]),
243 nsITransport::OPEN_UNBUFFERED
,
244 nsITransport::OPEN_UNBUFFERED
);
245 NS_ASSERTION(NS_SUCCEEDED(rv
), "RunCloseTest failed");
247 LOG(("flags = { OPEN_BUFFERED, OPEN_UNBUFFERED }\n"));
248 rv
= RunCloseTest(sts
, argv
[1], atoi(argv
[2]),
249 0 /* nsITransport::OPEN_BUFFERED */,
250 nsITransport::OPEN_UNBUFFERED
);
251 NS_ASSERTION(NS_SUCCEEDED(rv
), "RunCloseTest failed");
253 LOG(("flags = { OPEN_UNBUFFERED, OPEN_BUFFERED }\n"));
254 rv
= RunCloseTest(sts
, argv
[1], atoi(argv
[2]),
255 nsITransport::OPEN_UNBUFFERED
,
256 0 /*nsITransport::OPEN_BUFFERED */);
257 NS_ASSERTION(NS_SUCCEEDED(rv
), "RunCloseTest failed");
259 LOG(("flags = { OPEN_BUFFERED, OPEN_BUFFERED }\n"));
260 rv
= RunCloseTest(sts
, argv
[1], atoi(argv
[2]),
261 0 /*nsITransport::OPEN_BUFFERED */,
262 0 /*nsITransport::OPEN_BUFFERED */);
263 NS_ASSERTION(NS_SUCCEEDED(rv
), "RunCloseTest failed");
265 LOG(("calling Shutdown on socket transport service:\n"));
268 LOG(("calling Init on socket transport service:\n"));
271 LOG(("phase 2 tests...\n"));
273 LOG(("flags = { OPEN_UNBUFFERED, OPEN_UNBUFFERED }\n"));
274 rv
= RunTest(sts
, argv
[1], atoi(argv
[2]), argv
[3],
275 nsITransport::OPEN_UNBUFFERED
,
276 nsITransport::OPEN_UNBUFFERED
);
277 NS_ASSERTION(NS_SUCCEEDED(rv
), "RunTest failed");
279 LOG(("flags = { OPEN_BUFFERED, OPEN_UNBUFFERED }\n"));
280 rv
= RunTest(sts
, argv
[1], atoi(argv
[2]), argv
[3],
281 0 /* nsITransport::OPEN_BUFFERED */,
282 nsITransport::OPEN_UNBUFFERED
);
283 NS_ASSERTION(NS_SUCCEEDED(rv
), "RunTest failed");
285 LOG(("flags = { OPEN_UNBUFFERED, OPEN_BUFFERED }\n"));
286 rv
= RunTest(sts
, argv
[1], atoi(argv
[2]), argv
[3],
287 nsITransport::OPEN_UNBUFFERED
,
288 0 /*nsITransport::OPEN_BUFFERED */);
289 NS_ASSERTION(NS_SUCCEEDED(rv
), "RunTest failed");
291 LOG(("flags = { OPEN_BUFFERED, OPEN_BUFFERED }\n"));
292 rv
= RunTest(sts
, argv
[1], atoi(argv
[2]), argv
[3],
293 0 /*nsITransport::OPEN_BUFFERED */,
294 0 /*nsITransport::OPEN_BUFFERED */);
295 NS_ASSERTION(NS_SUCCEEDED(rv
), "RunTest failed");
297 LOG(("waiting 1 second before calling Shutdown...\n"));
298 PR_Sleep(PR_SecondsToInterval(1));
300 LOG(("calling Shutdown on socket transport service:\n"));
303 // give background threads a chance to finish whatever work they may
305 LOG(("waiting 1 second before exiting...\n"));
306 PR_Sleep(PR_SecondsToInterval(1));
307 } // this scopes the nsCOMPtrs
308 // no nsCOMPtrs are allowed to be alive when you call NS_ShutdownXPCOM
309 rv
= NS_ShutdownXPCOM(nullptr);
310 NS_ASSERTION(NS_SUCCEEDED(rv
), "NS_ShutdownXPCOM failed");