1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 #include "TestCommon.h"
14 #include "nsIIOService.h"
15 #include "nsIServiceManager.h"
16 #include "nsIStreamListener.h"
17 #include "nsIInputStream.h"
18 #include "nsIChannel.h"
20 #include "nsIInterfaceRequestor.h"
21 #include "nsIInterfaceRequestorUtils.h"
22 #include "nsIDNSService.h"
23 #include "mozilla/Attributes.h"
25 #include "nsISimpleEnumerator.h"
26 #include "nsNetUtil.h"
27 #include "nsStringAPI.h"
29 static NS_DEFINE_CID(kIOServiceCID
, NS_IOSERVICE_CID
);
31 static bool gError
= false;
32 static int32_t gKeepRunning
= 0;
34 #define NS_IEQUALS_IID \
35 { 0x11c5c8ee, 0x1dd2, 0x11b2, \
36 { 0xa8, 0x93, 0xbb, 0x23, 0xa1, 0xb6, 0x27, 0x76 }}
38 class nsIEquals
: public nsISupports
{
40 NS_DECLARE_STATIC_IID_ACCESSOR(NS_IEQUALS_IID
)
41 NS_IMETHOD
Equals(void *aPtr
, bool *_retval
) = 0;
44 NS_DEFINE_STATIC_IID_ACCESSOR(nsIEquals
, NS_IEQUALS_IID
)
46 class ConsumerContext MOZ_FINAL
: public nsIEquals
{
51 NS_DECL_THREADSAFE_ISUPPORTS
55 NS_IMETHOD
Equals(void *aPtr
, bool *_retval
) {
57 if (aPtr
!= this) *_retval
= false;
62 NS_IMPL_ISUPPORTS(ConsumerContext
, nsIEquals
)
64 class Consumer
: public nsIStreamListener
{
69 NS_DECL_THREADSAFE_ISUPPORTS
70 NS_DECL_NSIREQUESTOBSERVER
71 NS_DECL_NSISTREAMLISTENER
74 nsresult
Init(nsIURI
*aURI
, nsIChannel
*aChannel
, nsISupports
*aContext
);
75 nsresult
Validate(nsIRequest
*request
, nsISupports
*aContext
);
78 bool mOnStart
; // have we received an OnStart?
79 bool mOnStop
; // have we received an onStop?
80 int32_t mOnDataCount
; // number of times OnData was called.
81 nsCOMPtr
<nsIURI
> mURI
;
82 nsCOMPtr
<nsIChannel
> mChannel
;
83 nsCOMPtr
<nsIEquals
> mContext
;
86 // nsISupports implementation
87 NS_IMPL_ISUPPORTS(Consumer
, nsIStreamListener
, nsIRequestObserver
)
90 // nsIRequestObserver implementation
92 Consumer::OnStartRequest(nsIRequest
*request
, nsISupports
* aContext
) {
93 fprintf(stderr
, "Consumer::OnStart() -> in\n\n");
96 fprintf(stderr
, "INFO: multiple OnStarts received\n");
100 nsresult rv
= Validate(request
, aContext
);
101 if (NS_FAILED(rv
)) return rv
;
103 fprintf(stderr
, "Consumer::OnStart() -> out\n\n");
108 Consumer::OnStopRequest(nsIRequest
*request
, nsISupports
*aContext
,
110 fprintf(stderr
, "Consumer::OnStop() -> in\n\n");
114 fprintf(stderr
, "ERROR: No OnStart received\n");
118 fprintf(stderr
, "INFO: multiple OnStops received\n");
121 fprintf(stderr
, "INFO: received %d OnData()s\n", mOnDataCount
);
125 nsresult rv
= Validate(request
, aContext
);
126 if (NS_FAILED(rv
)) return rv
;
128 fprintf(stderr
, "Consumer::OnStop() -> out\n\n");
133 // nsIStreamListener implementation
135 Consumer::OnDataAvailable(nsIRequest
*request
, nsISupports
*aContext
,
136 nsIInputStream
*aIStream
,
137 uint64_t aOffset
, uint32_t aLength
) {
138 fprintf(stderr
, "Consumer::OnData() -> in\n\n");
142 fprintf(stderr
, "ERROR: No OnStart received\n");
147 nsresult rv
= Validate(request
, aContext
);
148 if (NS_FAILED(rv
)) return rv
;
150 fprintf(stderr
, "Consumer::OnData() -> out\n\n");
154 // Consumer implementation
155 Consumer::Consumer() {
156 mOnStart
= mOnStop
= false;
161 Consumer::~Consumer() {
162 fprintf(stderr
, "Consumer::~Consumer -> in\n\n");
166 fprintf(stderr
, "ERROR: Never got an OnStart\n");
171 fprintf(stderr
, "ERROR: Never got an OnStop \n");
174 fprintf(stderr
, "Consumer::~Consumer -> out\n\n");
175 if (--gKeepRunning
== 0)
180 Consumer::Init(nsIURI
*aURI
, nsIChannel
* aChannel
, nsISupports
*aContext
) {
183 mContext
= do_QueryInterface(aContext
);
188 Consumer::Validate(nsIRequest
* request
, nsISupports
*aContext
) {
190 nsCOMPtr
<nsIURI
> uri
;
191 nsCOMPtr
<nsIChannel
> aChannel
= do_QueryInterface(request
);
193 rv
= aChannel
->GetURI(getter_AddRefs(uri
));
194 if (NS_FAILED(rv
)) return rv
;
198 rv
= mURI
->Equals(uri
, &same
);
199 if (NS_FAILED(rv
)) return rv
;
202 fprintf(stderr
, "INFO: URIs do not match\n");
204 rv
= mContext
->Equals((void*)aContext
, &same
);
205 if (NS_FAILED(rv
)) return rv
;
209 fprintf(stderr
, "ERROR: Contexts do not match\n");
214 nsresult
StartLoad(const char *);
216 int main(int argc
, char *argv
[]) {
217 if (test_common_init(&argc
, &argv
) != 0)
221 bool cmdLineURL
= false;
224 // run in signle url mode
228 rv
= NS_InitXPCOM2(nullptr, nullptr, nullptr);
229 if (NS_FAILED(rv
)) return -1;
232 rv
= StartLoad(argv
[1]);
234 rv
= StartLoad("http://badhostnamexyz/test.txt");
236 if (NS_FAILED(rv
)) return -1;
238 // Enter the message pump to allow the URL load to proceed.
241 NS_ShutdownXPCOM(nullptr);
243 fprintf(stderr
, "\n\n-------ERROR-------\n\n");
248 nsresult
StartLoad(const char *aURISpec
) {
252 ConsumerContext
*context
= new ConsumerContext
;
253 nsCOMPtr
<nsISupports
> contextSup
= do_QueryInterface(context
, &rv
);
254 if (NS_FAILED(rv
)) return rv
;
257 nsCOMPtr
<nsIIOService
> serv
= do_GetService(kIOServiceCID
, &rv
);
258 if (NS_FAILED(rv
)) return rv
;
261 nsCOMPtr
<nsIURI
> uri
;
262 rv
= NS_NewURI(getter_AddRefs(uri
), aURISpec
);
263 if (NS_FAILED(rv
)) return rv
;
266 nsCOMPtr
<nsIChannel
> channel
;
267 rv
= serv
->NewChannelFromURI(uri
, getter_AddRefs(channel
));
268 if (NS_FAILED(rv
)) return rv
;
270 Consumer
*consumer
= new Consumer
;
271 rv
= consumer
->Init(uri
, channel
, contextSup
);
272 if (NS_FAILED(rv
)) return rv
;
275 nsCOMPtr
<nsIRequest
> request
;
276 return channel
->AsyncOpen(static_cast<nsIStreamListener
*>(consumer
), contextSup
);