Wed, 31 Dec 2014 06:55:46 +0100
Added tag TORBROWSER_REPLICA for changeset 6474c204b198
1 /* -*- Mode: C++; tab-width: 4; 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 "nsNetUtil.h"
8 #include "nsIServiceManager.h"
9 #include "nsIInterfaceRequestor.h"
10 #include "nsIInterfaceRequestorUtils.h"
11 #include "nsIProgressEventSink.h"
12 #include "nsIComponentManager.h"
13 #include "prprf.h"
14 #include "nsXPCOM.h"
15 #include "nsISupportsPrimitives.h"
16 #include "plstr.h"
17 #include "nsCOMArray.h"
18 #include "nsIComponentRegistrar.h"
19 #include <algorithm>
21 namespace TestPageLoad {
23 int getStrLine(const char *src, char *str, int ind, int max);
24 nsresult auxLoad(char *uriBuf);
25 //----------------------------------------------------------------------
28 #define RETURN_IF_FAILED(rv, ret, step) \
29 PR_BEGIN_MACRO \
30 if (NS_FAILED(rv)) { \
31 printf(">>> %s failed: rv=%x\n", step, static_cast<uint32_t>(rv)); \
32 return ret;\
33 } \
34 PR_END_MACRO
36 static nsCString globalStream;
37 //static char urlBuf[256];
38 static nsCOMPtr<nsIURI> baseURI;
39 static nsCOMArray<nsIURI> uriList;
41 //Temp, should remove:
42 static int numStart=0;
43 static int numFound=0;
45 static int32_t gKeepRunning = 0;
48 //--------writer fun----------------------
50 static NS_METHOD streamParse (nsIInputStream* in,
51 void* closure,
52 const char* fromRawSegment,
53 uint32_t toOffset,
54 uint32_t count,
55 uint32_t *writeCount) {
57 char parseBuf[2048], loc[2048], lineBuf[2048];
58 char *loc_t, *loc_t2;
59 int i = 0;
60 const char *tmp;
62 if(!globalStream.IsEmpty()) {
63 globalStream.Append(fromRawSegment);
64 tmp = globalStream.get();
65 //printf("\n>>NOW:\n^^^^^\n%s\n^^^^^^^^^^^^^^", tmp);
66 } else {
67 tmp = fromRawSegment;
68 }
70 while(i < (int)count) {
71 i = getStrLine(tmp, lineBuf, i, count);
72 if(i < 0) {
73 *writeCount = count;
74 return NS_OK;
75 }
76 parseBuf[0]='\0';
77 if((loc_t=PL_strcasestr(lineBuf, "img"))!= nullptr
78 || (loc_t=PL_strcasestr(lineBuf, "script"))!=nullptr) {
79 loc_t2=PL_strcasestr(loc_t, "src");
80 if(loc_t2!=nullptr) {
81 loc_t2+=3;
82 strcpy(loc, loc_t2);
83 sscanf(loc, "=\"%[^\"]", parseBuf);
84 if(parseBuf[0]=='\0')
85 sscanf(loc, "=%s", parseBuf);
86 if(parseBuf[0]!='\0'){
87 numFound++;
88 auxLoad(parseBuf);
89 }
90 }
91 }
93 /***NEED BETTER CHECK FOR STYLESHEETS
94 if((loc_t=PL_strcasestr(lineBuf, "link"))!= nullptr) {
95 loc_t2=PL_strcasestr(loc_t, "href");
96 if(loc_t2!=nullptr) {
97 loc_t2+=4;
98 strcpy(loc, loc_t2);
99 //printf("%s\n", loc);
100 sscanf(loc, "=\"%[^\"]", parseBuf);
101 if(parseBuf[0]!='\0'){
102 //printf("%s\n", parseBuf);
103 numFound++;
104 auxLoad(parseBuf);
105 }
106 }
107 }
108 */
109 if((loc_t=PL_strcasestr(lineBuf, "background"))!=nullptr) {
110 loc_t+=10;
111 strcpy(loc, loc_t);
112 sscanf(loc, "=\"%[^\"]", parseBuf);
113 if(parseBuf[0]!='\0') {
114 numFound++;
115 auxLoad(parseBuf);
116 }
117 }
118 i++;
120 }
121 *writeCount = count;
122 return NS_OK;
123 }
125 //-----------------------------------------------------------------------------
126 // nsIStreamListener implementation
127 //-----------------------------------------------------------------------------
129 class MyListener : public nsIStreamListener
130 {
131 public:
132 NS_DECL_ISUPPORTS
133 NS_DECL_NSIREQUESTOBSERVER
134 NS_DECL_NSISTREAMLISTENER
136 MyListener() { }
137 virtual ~MyListener() {}
138 };
140 NS_IMPL_ISUPPORTS(MyListener,
141 nsIRequestObserver,
142 nsIStreamListener)
144 NS_IMETHODIMP
145 MyListener::OnStartRequest(nsIRequest *req, nsISupports *ctxt)
146 {
147 //printf(">>> OnStartRequest\n");
148 numStart++;
149 return NS_OK;
150 }
152 NS_IMETHODIMP
153 MyListener::OnStopRequest(nsIRequest *req, nsISupports *ctxt, nsresult status)
154 {
155 //printf(">>> OnStopRequest status=%x\n", status);
156 if (--gKeepRunning == 0)
157 QuitPumpingEvents();
158 return NS_OK;
159 }
161 NS_IMETHODIMP
162 MyListener::OnDataAvailable(nsIRequest *req, nsISupports *ctxt,
163 nsIInputStream *stream,
164 uint64_t offset, uint32_t count)
165 {
166 //printf(">>> OnDataAvailable [count=%u]\n", count);
167 nsresult rv = NS_ERROR_FAILURE;
168 uint32_t bytesRead=0;
169 char buf[1024];
171 if(ctxt == nullptr) {
172 bytesRead=0;
173 rv = stream->ReadSegments(streamParse, nullptr, count, &bytesRead);
174 } else {
175 while (count) {
176 uint32_t amount = std::min<uint32_t>(count, sizeof(buf));
177 rv = stream->Read(buf, amount, &bytesRead);
178 count -= bytesRead;
179 }
180 }
182 if (NS_FAILED(rv)) {
183 printf(">>> stream->Read failed with rv=%x\n",
184 static_cast<uint32_t>(rv));
185 return rv;
186 }
188 return NS_OK;
189 }
191 //-----------------------------------------------------------------------------
192 // NotificationCallbacks implementation
193 //-----------------------------------------------------------------------------
195 class MyNotifications : public nsIInterfaceRequestor
196 , public nsIProgressEventSink
197 {
198 public:
199 NS_DECL_THREADSAFE_ISUPPORTS
200 NS_DECL_NSIINTERFACEREQUESTOR
201 NS_DECL_NSIPROGRESSEVENTSINK
203 MyNotifications() { }
204 virtual ~MyNotifications() {}
205 };
207 NS_IMPL_ISUPPORTS(MyNotifications,
208 nsIInterfaceRequestor,
209 nsIProgressEventSink)
211 NS_IMETHODIMP
212 MyNotifications::GetInterface(const nsIID &iid, void **result)
213 {
214 return QueryInterface(iid, result);
215 }
217 NS_IMETHODIMP
218 MyNotifications::OnStatus(nsIRequest *req, nsISupports *ctx,
219 nsresult status, const char16_t *statusText)
220 {
221 //printf("status: %x\n", status);
222 return NS_OK;
223 }
225 NS_IMETHODIMP
226 MyNotifications::OnProgress(nsIRequest *req, nsISupports *ctx,
227 uint64_t progress, uint64_t progressMax)
228 {
229 // char buf[100];
230 // PR_snprintf(buf, sizeof(buf), "%llu/%llu\n", progress, progressMax);
231 // printf("%s", buf);
232 return NS_OK;
233 }
235 //-----------------------------------------------------------------------------
236 // main, etc..
237 //-----------------------------------------------------------------------------
239 //---------getStrLine Helper function---------------
240 //Finds a newline in src starting at ind. Puts the
241 //line in str (must be big enough). Returns the index
242 //of the newline, or -1 if at end of string. If reaches
243 //end of string ('\0'), then will copy contents to
244 //globalStream.
245 int getStrLine(const char *src, char *str, int ind, int max) {
246 char c = src[ind];
247 int i=0;
248 globalStream.Assign('\0');
249 while(c!='\n' && c!='\0' && i<max) {
250 str[i] = src[ind];
251 i++; ind++;
252 c = src[ind];
253 }
254 str[i]='\0';
255 if(i==max || c=='\0') {
256 globalStream.Assign(str);
257 //printf("\nCarryover (%d|%d):\n------------\n%s\n-------\n",i,max,str);
258 return -1;
259 }
260 return ind;
261 }
263 //----------AUX LOAD-----------
264 nsresult auxLoad(char *uriBuf)
265 {
266 nsresult rv;
268 nsCOMPtr<nsISupportsPRBool> myBool = do_CreateInstance(NS_SUPPORTS_PRBOOL_CONTRACTID);
270 nsCOMPtr<nsIURI> uri;
271 nsCOMPtr<nsIChannel> chan;
272 nsCOMPtr<nsIStreamListener> listener = new MyListener();
273 nsCOMPtr<nsIInterfaceRequestor> callbacks = new MyNotifications();
275 printf("Getting: %s", uriBuf);
277 //If relative link
278 if(strncmp(uriBuf, "http:", 5)) {
279 //Relative link
280 rv = NS_NewURI(getter_AddRefs(uri), uriBuf, baseURI);
281 if (NS_FAILED(rv)) return(rv);
282 } else {
283 //Absolute link, no base needed
284 rv = NS_NewURI(getter_AddRefs(uri), uriBuf);
285 if (NS_FAILED(rv)) return(rv);
286 }
288 //Compare to see if exists
289 bool equal;
290 for(int32_t i = 0; i < uriList.Count(); i++) {
291 uri->Equals(uriList[i], &equal);
292 if(equal) {
293 printf("(duplicate, canceling) %s\n",uriBuf);
294 return NS_OK;
295 }
296 }
297 printf("\n");
298 uriList.AppendObject(uri);
299 rv = NS_NewChannel(getter_AddRefs(chan), uri, nullptr, nullptr, callbacks);
300 RETURN_IF_FAILED(rv, rv, "NS_NewChannel");
302 gKeepRunning++;
303 rv = chan->AsyncOpen(listener, myBool);
304 RETURN_IF_FAILED(rv, rv, "AsyncOpen");
306 return NS_OK;
308 }
310 //---------Buffer writer fun---------
312 } // namespace
314 using namespace TestPageLoad;
316 //---------MAIN-----------
318 int main(int argc, char **argv)
319 {
320 if (test_common_init(&argc, &argv) != 0)
321 return -1;
323 nsresult rv;
325 if (argc == 1) {
326 printf("usage: TestPageLoad <url>\n");
327 return -1;
328 }
329 {
330 nsCOMPtr<nsIServiceManager> servMan;
331 NS_InitXPCOM2(getter_AddRefs(servMan), nullptr, nullptr);
333 PRTime start, finish;
335 printf("Loading necko ... \n");
336 nsCOMPtr<nsIChannel> chan;
337 nsCOMPtr<nsIStreamListener> listener = new MyListener();
338 nsCOMPtr<nsIInterfaceRequestor> callbacks = new MyNotifications();
340 rv = NS_NewURI(getter_AddRefs(baseURI), argv[1]);
341 RETURN_IF_FAILED(rv, -1, "NS_NewURI");
343 rv = NS_NewChannel(getter_AddRefs(chan), baseURI, nullptr, nullptr, callbacks);
344 RETURN_IF_FAILED(rv, -1, "NS_OpenURI");
345 gKeepRunning++;
347 //TIMER STARTED-----------------------
348 printf("Starting clock ... \n");
349 start = PR_Now();
350 rv = chan->AsyncOpen(listener, nullptr);
351 RETURN_IF_FAILED(rv, -1, "AsyncOpen");
353 PumpEvents();
355 finish = PR_Now();
356 uint32_t totalTime32 = uint32_t(finish - start);
358 printf("\n\n--------------------\nAll done:\nnum found:%d\nnum start:%d\n", numFound, numStart);
360 printf("\n\n>>PageLoadTime>>%u>>\n\n", totalTime32);
361 } // this scopes the nsCOMPtrs
362 // no nsCOMPtrs are allowed to be alive when you call NS_ShutdownXPCOM
363 rv = NS_ShutdownXPCOM(nullptr);
364 NS_ASSERTION(NS_SUCCEEDED(rv), "NS_ShutdownXPCOM failed");
365 return 0;
366 }