1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/netwerk/test/TestPageLoad.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,366 @@ 1.4 +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.8 + 1.9 +#include "TestCommon.h" 1.10 +#include "nsNetUtil.h" 1.11 +#include "nsIServiceManager.h" 1.12 +#include "nsIInterfaceRequestor.h" 1.13 +#include "nsIInterfaceRequestorUtils.h" 1.14 +#include "nsIProgressEventSink.h" 1.15 +#include "nsIComponentManager.h" 1.16 +#include "prprf.h" 1.17 +#include "nsXPCOM.h" 1.18 +#include "nsISupportsPrimitives.h" 1.19 +#include "plstr.h" 1.20 +#include "nsCOMArray.h" 1.21 +#include "nsIComponentRegistrar.h" 1.22 +#include <algorithm> 1.23 + 1.24 +namespace TestPageLoad { 1.25 + 1.26 +int getStrLine(const char *src, char *str, int ind, int max); 1.27 +nsresult auxLoad(char *uriBuf); 1.28 +//---------------------------------------------------------------------- 1.29 + 1.30 + 1.31 +#define RETURN_IF_FAILED(rv, ret, step) \ 1.32 + PR_BEGIN_MACRO \ 1.33 + if (NS_FAILED(rv)) { \ 1.34 + printf(">>> %s failed: rv=%x\n", step, static_cast<uint32_t>(rv)); \ 1.35 + return ret;\ 1.36 + } \ 1.37 + PR_END_MACRO 1.38 + 1.39 +static nsCString globalStream; 1.40 +//static char urlBuf[256]; 1.41 +static nsCOMPtr<nsIURI> baseURI; 1.42 +static nsCOMArray<nsIURI> uriList; 1.43 + 1.44 +//Temp, should remove: 1.45 +static int numStart=0; 1.46 +static int numFound=0; 1.47 + 1.48 +static int32_t gKeepRunning = 0; 1.49 + 1.50 + 1.51 +//--------writer fun---------------------- 1.52 + 1.53 +static NS_METHOD streamParse (nsIInputStream* in, 1.54 + void* closure, 1.55 + const char* fromRawSegment, 1.56 + uint32_t toOffset, 1.57 + uint32_t count, 1.58 + uint32_t *writeCount) { 1.59 + 1.60 + char parseBuf[2048], loc[2048], lineBuf[2048]; 1.61 + char *loc_t, *loc_t2; 1.62 + int i = 0; 1.63 + const char *tmp; 1.64 + 1.65 + if(!globalStream.IsEmpty()) { 1.66 + globalStream.Append(fromRawSegment); 1.67 + tmp = globalStream.get(); 1.68 + //printf("\n>>NOW:\n^^^^^\n%s\n^^^^^^^^^^^^^^", tmp); 1.69 + } else { 1.70 + tmp = fromRawSegment; 1.71 + } 1.72 + 1.73 + while(i < (int)count) { 1.74 + i = getStrLine(tmp, lineBuf, i, count); 1.75 + if(i < 0) { 1.76 + *writeCount = count; 1.77 + return NS_OK; 1.78 + } 1.79 + parseBuf[0]='\0'; 1.80 + if((loc_t=PL_strcasestr(lineBuf, "img"))!= nullptr 1.81 + || (loc_t=PL_strcasestr(lineBuf, "script"))!=nullptr) { 1.82 + loc_t2=PL_strcasestr(loc_t, "src"); 1.83 + if(loc_t2!=nullptr) { 1.84 + loc_t2+=3; 1.85 + strcpy(loc, loc_t2); 1.86 + sscanf(loc, "=\"%[^\"]", parseBuf); 1.87 + if(parseBuf[0]=='\0') 1.88 + sscanf(loc, "=%s", parseBuf); 1.89 + if(parseBuf[0]!='\0'){ 1.90 + numFound++; 1.91 + auxLoad(parseBuf); 1.92 + } 1.93 + } 1.94 + } 1.95 + 1.96 + /***NEED BETTER CHECK FOR STYLESHEETS 1.97 + if((loc_t=PL_strcasestr(lineBuf, "link"))!= nullptr) { 1.98 + loc_t2=PL_strcasestr(loc_t, "href"); 1.99 + if(loc_t2!=nullptr) { 1.100 + loc_t2+=4; 1.101 + strcpy(loc, loc_t2); 1.102 + //printf("%s\n", loc); 1.103 + sscanf(loc, "=\"%[^\"]", parseBuf); 1.104 + if(parseBuf[0]!='\0'){ 1.105 + //printf("%s\n", parseBuf); 1.106 + numFound++; 1.107 + auxLoad(parseBuf); 1.108 + } 1.109 + } 1.110 + } 1.111 + */ 1.112 + if((loc_t=PL_strcasestr(lineBuf, "background"))!=nullptr) { 1.113 + loc_t+=10; 1.114 + strcpy(loc, loc_t); 1.115 + sscanf(loc, "=\"%[^\"]", parseBuf); 1.116 + if(parseBuf[0]!='\0') { 1.117 + numFound++; 1.118 + auxLoad(parseBuf); 1.119 + } 1.120 + } 1.121 + i++; 1.122 + 1.123 + } 1.124 + *writeCount = count; 1.125 + return NS_OK; 1.126 +} 1.127 + 1.128 +//----------------------------------------------------------------------------- 1.129 +// nsIStreamListener implementation 1.130 +//----------------------------------------------------------------------------- 1.131 + 1.132 +class MyListener : public nsIStreamListener 1.133 +{ 1.134 +public: 1.135 + NS_DECL_ISUPPORTS 1.136 + NS_DECL_NSIREQUESTOBSERVER 1.137 + NS_DECL_NSISTREAMLISTENER 1.138 + 1.139 + MyListener() { } 1.140 + virtual ~MyListener() {} 1.141 +}; 1.142 + 1.143 +NS_IMPL_ISUPPORTS(MyListener, 1.144 + nsIRequestObserver, 1.145 + nsIStreamListener) 1.146 + 1.147 +NS_IMETHODIMP 1.148 +MyListener::OnStartRequest(nsIRequest *req, nsISupports *ctxt) 1.149 +{ 1.150 + //printf(">>> OnStartRequest\n"); 1.151 + numStart++; 1.152 + return NS_OK; 1.153 +} 1.154 + 1.155 +NS_IMETHODIMP 1.156 +MyListener::OnStopRequest(nsIRequest *req, nsISupports *ctxt, nsresult status) 1.157 +{ 1.158 + //printf(">>> OnStopRequest status=%x\n", status); 1.159 + if (--gKeepRunning == 0) 1.160 + QuitPumpingEvents(); 1.161 + return NS_OK; 1.162 +} 1.163 + 1.164 +NS_IMETHODIMP 1.165 +MyListener::OnDataAvailable(nsIRequest *req, nsISupports *ctxt, 1.166 + nsIInputStream *stream, 1.167 + uint64_t offset, uint32_t count) 1.168 +{ 1.169 + //printf(">>> OnDataAvailable [count=%u]\n", count); 1.170 + nsresult rv = NS_ERROR_FAILURE; 1.171 + uint32_t bytesRead=0; 1.172 + char buf[1024]; 1.173 + 1.174 + if(ctxt == nullptr) { 1.175 + bytesRead=0; 1.176 + rv = stream->ReadSegments(streamParse, nullptr, count, &bytesRead); 1.177 + } else { 1.178 + while (count) { 1.179 + uint32_t amount = std::min<uint32_t>(count, sizeof(buf)); 1.180 + rv = stream->Read(buf, amount, &bytesRead); 1.181 + count -= bytesRead; 1.182 + } 1.183 + } 1.184 + 1.185 + if (NS_FAILED(rv)) { 1.186 + printf(">>> stream->Read failed with rv=%x\n", 1.187 + static_cast<uint32_t>(rv)); 1.188 + return rv; 1.189 + } 1.190 + 1.191 + return NS_OK; 1.192 +} 1.193 + 1.194 +//----------------------------------------------------------------------------- 1.195 +// NotificationCallbacks implementation 1.196 +//----------------------------------------------------------------------------- 1.197 + 1.198 +class MyNotifications : public nsIInterfaceRequestor 1.199 + , public nsIProgressEventSink 1.200 +{ 1.201 +public: 1.202 + NS_DECL_THREADSAFE_ISUPPORTS 1.203 + NS_DECL_NSIINTERFACEREQUESTOR 1.204 + NS_DECL_NSIPROGRESSEVENTSINK 1.205 + 1.206 + MyNotifications() { } 1.207 + virtual ~MyNotifications() {} 1.208 +}; 1.209 + 1.210 +NS_IMPL_ISUPPORTS(MyNotifications, 1.211 + nsIInterfaceRequestor, 1.212 + nsIProgressEventSink) 1.213 + 1.214 +NS_IMETHODIMP 1.215 +MyNotifications::GetInterface(const nsIID &iid, void **result) 1.216 +{ 1.217 + return QueryInterface(iid, result); 1.218 +} 1.219 + 1.220 +NS_IMETHODIMP 1.221 +MyNotifications::OnStatus(nsIRequest *req, nsISupports *ctx, 1.222 + nsresult status, const char16_t *statusText) 1.223 +{ 1.224 + //printf("status: %x\n", status); 1.225 + return NS_OK; 1.226 +} 1.227 + 1.228 +NS_IMETHODIMP 1.229 +MyNotifications::OnProgress(nsIRequest *req, nsISupports *ctx, 1.230 + uint64_t progress, uint64_t progressMax) 1.231 +{ 1.232 + // char buf[100]; 1.233 + // PR_snprintf(buf, sizeof(buf), "%llu/%llu\n", progress, progressMax); 1.234 + // printf("%s", buf); 1.235 + return NS_OK; 1.236 +} 1.237 + 1.238 +//----------------------------------------------------------------------------- 1.239 +// main, etc.. 1.240 +//----------------------------------------------------------------------------- 1.241 + 1.242 +//---------getStrLine Helper function--------------- 1.243 +//Finds a newline in src starting at ind. Puts the 1.244 +//line in str (must be big enough). Returns the index 1.245 +//of the newline, or -1 if at end of string. If reaches 1.246 +//end of string ('\0'), then will copy contents to 1.247 +//globalStream. 1.248 +int getStrLine(const char *src, char *str, int ind, int max) { 1.249 + char c = src[ind]; 1.250 + int i=0; 1.251 + globalStream.Assign('\0'); 1.252 + while(c!='\n' && c!='\0' && i<max) { 1.253 + str[i] = src[ind]; 1.254 + i++; ind++; 1.255 + c = src[ind]; 1.256 + } 1.257 + str[i]='\0'; 1.258 + if(i==max || c=='\0') { 1.259 + globalStream.Assign(str); 1.260 + //printf("\nCarryover (%d|%d):\n------------\n%s\n-------\n",i,max,str); 1.261 + return -1; 1.262 + } 1.263 + return ind; 1.264 +} 1.265 + 1.266 +//----------AUX LOAD----------- 1.267 +nsresult auxLoad(char *uriBuf) 1.268 +{ 1.269 + nsresult rv; 1.270 + 1.271 + nsCOMPtr<nsISupportsPRBool> myBool = do_CreateInstance(NS_SUPPORTS_PRBOOL_CONTRACTID); 1.272 + 1.273 + nsCOMPtr<nsIURI> uri; 1.274 + nsCOMPtr<nsIChannel> chan; 1.275 + nsCOMPtr<nsIStreamListener> listener = new MyListener(); 1.276 + nsCOMPtr<nsIInterfaceRequestor> callbacks = new MyNotifications(); 1.277 + 1.278 + printf("Getting: %s", uriBuf); 1.279 + 1.280 + //If relative link 1.281 + if(strncmp(uriBuf, "http:", 5)) { 1.282 + //Relative link 1.283 + rv = NS_NewURI(getter_AddRefs(uri), uriBuf, baseURI); 1.284 + if (NS_FAILED(rv)) return(rv); 1.285 + } else { 1.286 + //Absolute link, no base needed 1.287 + rv = NS_NewURI(getter_AddRefs(uri), uriBuf); 1.288 + if (NS_FAILED(rv)) return(rv); 1.289 + } 1.290 + 1.291 + //Compare to see if exists 1.292 + bool equal; 1.293 + for(int32_t i = 0; i < uriList.Count(); i++) { 1.294 + uri->Equals(uriList[i], &equal); 1.295 + if(equal) { 1.296 + printf("(duplicate, canceling) %s\n",uriBuf); 1.297 + return NS_OK; 1.298 + } 1.299 + } 1.300 + printf("\n"); 1.301 + uriList.AppendObject(uri); 1.302 + rv = NS_NewChannel(getter_AddRefs(chan), uri, nullptr, nullptr, callbacks); 1.303 + RETURN_IF_FAILED(rv, rv, "NS_NewChannel"); 1.304 + 1.305 + gKeepRunning++; 1.306 + rv = chan->AsyncOpen(listener, myBool); 1.307 + RETURN_IF_FAILED(rv, rv, "AsyncOpen"); 1.308 + 1.309 + return NS_OK; 1.310 + 1.311 +} 1.312 + 1.313 +//---------Buffer writer fun--------- 1.314 + 1.315 +} // namespace 1.316 + 1.317 +using namespace TestPageLoad; 1.318 + 1.319 +//---------MAIN----------- 1.320 + 1.321 +int main(int argc, char **argv) 1.322 +{ 1.323 + if (test_common_init(&argc, &argv) != 0) 1.324 + return -1; 1.325 + 1.326 + nsresult rv; 1.327 + 1.328 + if (argc == 1) { 1.329 + printf("usage: TestPageLoad <url>\n"); 1.330 + return -1; 1.331 + } 1.332 + { 1.333 + nsCOMPtr<nsIServiceManager> servMan; 1.334 + NS_InitXPCOM2(getter_AddRefs(servMan), nullptr, nullptr); 1.335 + 1.336 + PRTime start, finish; 1.337 + 1.338 + printf("Loading necko ... \n"); 1.339 + nsCOMPtr<nsIChannel> chan; 1.340 + nsCOMPtr<nsIStreamListener> listener = new MyListener(); 1.341 + nsCOMPtr<nsIInterfaceRequestor> callbacks = new MyNotifications(); 1.342 + 1.343 + rv = NS_NewURI(getter_AddRefs(baseURI), argv[1]); 1.344 + RETURN_IF_FAILED(rv, -1, "NS_NewURI"); 1.345 + 1.346 + rv = NS_NewChannel(getter_AddRefs(chan), baseURI, nullptr, nullptr, callbacks); 1.347 + RETURN_IF_FAILED(rv, -1, "NS_OpenURI"); 1.348 + gKeepRunning++; 1.349 + 1.350 + //TIMER STARTED----------------------- 1.351 + printf("Starting clock ... \n"); 1.352 + start = PR_Now(); 1.353 + rv = chan->AsyncOpen(listener, nullptr); 1.354 + RETURN_IF_FAILED(rv, -1, "AsyncOpen"); 1.355 + 1.356 + PumpEvents(); 1.357 + 1.358 + finish = PR_Now(); 1.359 + uint32_t totalTime32 = uint32_t(finish - start); 1.360 + 1.361 + printf("\n\n--------------------\nAll done:\nnum found:%d\nnum start:%d\n", numFound, numStart); 1.362 + 1.363 + printf("\n\n>>PageLoadTime>>%u>>\n\n", totalTime32); 1.364 + } // this scopes the nsCOMPtrs 1.365 + // no nsCOMPtrs are allowed to be alive when you call NS_ShutdownXPCOM 1.366 + rv = NS_ShutdownXPCOM(nullptr); 1.367 + NS_ASSERTION(NS_SUCCEEDED(rv), "NS_ShutdownXPCOM failed"); 1.368 + return 0; 1.369 +}