Wed, 31 Dec 2014 06:55:46 +0100
Added tag TORBROWSER_REPLICA for changeset 6474c204b198
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"
7 #include <stdio.h>
8 #ifdef WIN32
9 #include <windows.h>
10 #endif
11 #include "nspr.h"
12 #include "nscore.h"
13 #include "nsCOMPtr.h"
14 #include "nsIIOService.h"
15 #include "nsIServiceManager.h"
16 #include "nsIStreamListener.h"
17 #include "nsIInputStream.h"
18 #include "nsIChannel.h"
19 #include "nsIURL.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 {
39 public:
40 NS_DECLARE_STATIC_IID_ACCESSOR(NS_IEQUALS_IID)
41 NS_IMETHOD Equals(void *aPtr, bool *_retval) = 0;
42 };
44 NS_DEFINE_STATIC_IID_ACCESSOR(nsIEquals, NS_IEQUALS_IID)
46 class ConsumerContext MOZ_FINAL : public nsIEquals {
47 public:
48 NS_DECL_THREADSAFE_ISUPPORTS
50 ConsumerContext() { }
52 NS_IMETHOD Equals(void *aPtr, bool *_retval) {
53 *_retval = true;
54 if (aPtr != this) *_retval = false;
55 return NS_OK;
56 }
57 };
59 NS_IMPL_ISUPPORTS(ConsumerContext, nsIEquals)
61 class Consumer : public nsIStreamListener {
62 public:
63 NS_DECL_THREADSAFE_ISUPPORTS
64 NS_DECL_NSIREQUESTOBSERVER
65 NS_DECL_NSISTREAMLISTENER
67 Consumer();
68 virtual ~Consumer();
69 nsresult Init(nsIURI *aURI, nsIChannel *aChannel, nsISupports *aContext);
70 nsresult Validate(nsIRequest *request, nsISupports *aContext);
72 // member data
73 bool mOnStart; // have we received an OnStart?
74 bool mOnStop; // have we received an onStop?
75 int32_t mOnDataCount; // number of times OnData was called.
76 nsCOMPtr<nsIURI> mURI;
77 nsCOMPtr<nsIChannel> mChannel;
78 nsCOMPtr<nsIEquals> mContext;
79 };
81 // nsISupports implementation
82 NS_IMPL_ISUPPORTS(Consumer, nsIStreamListener, nsIRequestObserver)
85 // nsIRequestObserver implementation
86 NS_IMETHODIMP
87 Consumer::OnStartRequest(nsIRequest *request, nsISupports* aContext) {
88 fprintf(stderr, "Consumer::OnStart() -> in\n\n");
90 if (mOnStart) {
91 fprintf(stderr, "INFO: multiple OnStarts received\n");
92 }
93 mOnStart = true;
95 nsresult rv = Validate(request, aContext);
96 if (NS_FAILED(rv)) return rv;
98 fprintf(stderr, "Consumer::OnStart() -> out\n\n");
99 return rv;
100 }
102 NS_IMETHODIMP
103 Consumer::OnStopRequest(nsIRequest *request, nsISupports *aContext,
104 nsresult aStatus) {
105 fprintf(stderr, "Consumer::OnStop() -> in\n\n");
107 if (!mOnStart) {
108 gError = true;
109 fprintf(stderr, "ERROR: No OnStart received\n");
110 }
112 if (mOnStop) {
113 fprintf(stderr, "INFO: multiple OnStops received\n");
114 }
116 fprintf(stderr, "INFO: received %d OnData()s\n", mOnDataCount);
118 mOnStop = true;
120 nsresult rv = Validate(request, aContext);
121 if (NS_FAILED(rv)) return rv;
123 fprintf(stderr, "Consumer::OnStop() -> out\n\n");
124 return rv;
125 }
128 // nsIStreamListener implementation
129 NS_IMETHODIMP
130 Consumer::OnDataAvailable(nsIRequest *request, nsISupports *aContext,
131 nsIInputStream *aIStream,
132 uint64_t aOffset, uint32_t aLength) {
133 fprintf(stderr, "Consumer::OnData() -> in\n\n");
135 if (!mOnStart) {
136 gError = true;
137 fprintf(stderr, "ERROR: No OnStart received\n");
138 }
140 mOnDataCount += 1;
142 nsresult rv = Validate(request, aContext);
143 if (NS_FAILED(rv)) return rv;
145 fprintf(stderr, "Consumer::OnData() -> out\n\n");
146 return rv;
147 }
149 // Consumer implementation
150 Consumer::Consumer() {
151 mOnStart = mOnStop = false;
152 mOnDataCount = 0;
153 gKeepRunning++;
154 }
156 Consumer::~Consumer() {
157 fprintf(stderr, "Consumer::~Consumer -> in\n\n");
159 if (!mOnStart) {
160 gError = true;
161 fprintf(stderr, "ERROR: Never got an OnStart\n");
162 }
164 if (!mOnStop) {
165 gError = true;
166 fprintf(stderr, "ERROR: Never got an OnStop \n");
167 }
169 fprintf(stderr, "Consumer::~Consumer -> out\n\n");
170 if (--gKeepRunning == 0)
171 QuitPumpingEvents();
172 }
174 nsresult
175 Consumer::Init(nsIURI *aURI, nsIChannel* aChannel, nsISupports *aContext) {
176 mURI = aURI;
177 mChannel = aChannel;
178 mContext = do_QueryInterface(aContext);
179 return NS_OK;
180 }
182 nsresult
183 Consumer::Validate(nsIRequest* request, nsISupports *aContext) {
184 nsresult rv = NS_OK;
185 nsCOMPtr<nsIURI> uri;
186 nsCOMPtr<nsIChannel> aChannel = do_QueryInterface(request);
188 rv = aChannel->GetURI(getter_AddRefs(uri));
189 if (NS_FAILED(rv)) return rv;
191 bool same = false;
193 rv = mURI->Equals(uri, &same);
194 if (NS_FAILED(rv)) return rv;
196 if (!same)
197 fprintf(stderr, "INFO: URIs do not match\n");
199 rv = mContext->Equals((void*)aContext, &same);
200 if (NS_FAILED(rv)) return rv;
202 if (!same) {
203 gError = true;
204 fprintf(stderr, "ERROR: Contexts do not match\n");
205 }
206 return rv;
207 }
209 nsresult StartLoad(const char *);
211 int main(int argc, char *argv[]) {
212 if (test_common_init(&argc, &argv) != 0)
213 return -1;
215 nsresult rv = NS_OK;
216 bool cmdLineURL = false;
218 if (argc > 1) {
219 // run in signle url mode
220 cmdLineURL = true;
221 }
223 rv = NS_InitXPCOM2(nullptr, nullptr, nullptr);
224 if (NS_FAILED(rv)) return -1;
226 if (cmdLineURL) {
227 rv = StartLoad(argv[1]);
228 } else {
229 rv = StartLoad("http://badhostnamexyz/test.txt");
230 }
231 if (NS_FAILED(rv)) return -1;
233 // Enter the message pump to allow the URL load to proceed.
234 PumpEvents();
236 NS_ShutdownXPCOM(nullptr);
237 if (gError) {
238 fprintf(stderr, "\n\n-------ERROR-------\n\n");
239 }
240 return 0;
241 }
243 nsresult StartLoad(const char *aURISpec) {
244 nsresult rv = NS_OK;
246 // create a context
247 ConsumerContext *context = new ConsumerContext;
248 nsCOMPtr<nsISupports> contextSup = do_QueryInterface(context, &rv);
249 if (NS_FAILED(rv)) return rv;
252 nsCOMPtr<nsIIOService> serv = do_GetService(kIOServiceCID, &rv);
253 if (NS_FAILED(rv)) return rv;
255 // create a uri
256 nsCOMPtr<nsIURI> uri;
257 rv = NS_NewURI(getter_AddRefs(uri), aURISpec);
258 if (NS_FAILED(rv)) return rv;
260 // create a channel
261 nsCOMPtr<nsIChannel> channel;
262 rv = serv->NewChannelFromURI(uri, getter_AddRefs(channel));
263 if (NS_FAILED(rv)) return rv;
265 Consumer *consumer = new Consumer;
266 rv = consumer->Init(uri, channel, contextSup);
267 if (NS_FAILED(rv)) return rv;
269 // kick off the load
270 nsCOMPtr<nsIRequest> request;
271 return channel->AsyncOpen(static_cast<nsIStreamListener*>(consumer), contextSup);
272 }