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