1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/netwerk/test/TestOverlappedIO.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,319 @@ 1.4 +/* -*- Mode: C++; tab-width: 2; 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 +#include <stdio.h> 1.9 +#include <signal.h> 1.10 +#include <algorithm> 1.11 + 1.12 +#ifdef WIN32 1.13 +#include <windows.h> 1.14 +#endif 1.15 + 1.16 +#include "nspr.h" 1.17 +#include "nscore.h" 1.18 +#include "nsISocketTransportService.h" 1.19 +#include "nsIEventQueueService.h" 1.20 +#include "nsIServiceManager.h" 1.21 +#include "nsITransport.h" 1.22 +#include "nsIRequest.h" 1.23 +#include "nsIStreamProvider.h" 1.24 +#include "nsIStreamListener.h" 1.25 +#include "nsIPipe.h" 1.26 +#include "nsIOutputStream.h" 1.27 +#include "nsIInputStream.h" 1.28 +#include "nsCRT.h" 1.29 +#include "nsCOMPtr.h" 1.30 +#include "nsIByteArrayInputStream.h" 1.31 + 1.32 +#if defined(PR_LOGGING) 1.33 +static PRLogModuleInfo *gTestSocketIOLog; 1.34 +#define LOG(args) PR_LOG(gTestSocketIOLog, PR_LOG_DEBUG, args) 1.35 +#else 1.36 +#define LOG(args) 1.37 +#endif 1.38 + 1.39 +static NS_DEFINE_CID(kSocketTransportServiceCID, NS_SOCKETTRANSPORTSERVICE_CID); 1.40 +static NS_DEFINE_CID(kEventQueueServiceCID, NS_EVENTQUEUESERVICE_CID); 1.41 + 1.42 +static PRTime gElapsedTime; 1.43 +static int gKeepRunning = 1; 1.44 +static nsIEventQueue* gEventQ = nullptr; 1.45 + 1.46 +// 1.47 +//---------------------------------------------------------------------------- 1.48 +// Test Listener 1.49 +//---------------------------------------------------------------------------- 1.50 +// 1.51 + 1.52 +class TestListener : public nsIStreamListener 1.53 +{ 1.54 +public: 1.55 + TestListener() { } 1.56 + virtual ~TestListener() {} 1.57 + 1.58 + NS_DECL_ISUPPORTS 1.59 + NS_DECL_NSIREQUESTOBSERVER 1.60 + NS_DECL_NSISTREAMLISTENER 1.61 +}; 1.62 + 1.63 +NS_IMPL_ISUPPORTS(TestListener, 1.64 + nsIRequestObserver, 1.65 + nsIStreamListener); 1.66 + 1.67 +NS_IMETHODIMP 1.68 +TestListener::OnStartRequest(nsIRequest* request, nsISupports* context) 1.69 +{ 1.70 + LOG(("TestListener::OnStartRequest\n")); 1.71 + return NS_OK; 1.72 +} 1.73 + 1.74 +NS_IMETHODIMP 1.75 +TestListener::OnDataAvailable(nsIRequest* request, 1.76 + nsISupports* context, 1.77 + nsIInputStream *aIStream, 1.78 + uint64_t aSourceOffset, 1.79 + uint32_t aLength) 1.80 +{ 1.81 + LOG(("TestListener::OnDataAvailable [offset=%llu length=%u]\n", 1.82 + aSourceOffset, aLength)); 1.83 + char buf[1025]; 1.84 + uint32_t amt; 1.85 + while (1) { 1.86 + aIStream->Read(buf, 1024, &amt); 1.87 + if (amt == 0) 1.88 + break; 1.89 + buf[amt] = '\0'; 1.90 + //puts(buf); 1.91 + printf("read %d bytes\n", amt); 1.92 + } 1.93 + return NS_OK; 1.94 +} 1.95 + 1.96 +NS_IMETHODIMP 1.97 +TestListener::OnStopRequest(nsIRequest* request, nsISupports* context, 1.98 + nsresult aStatus) 1.99 +{ 1.100 + LOG(("TestListener::OnStopRequest [aStatus=%x]\n", aStatus)); 1.101 + //gKeepRunning = 0; 1.102 + return NS_OK; 1.103 +} 1.104 + 1.105 +// 1.106 +//---------------------------------------------------------------------------- 1.107 +// Test Provider 1.108 +//---------------------------------------------------------------------------- 1.109 +// 1.110 + 1.111 +class TestProvider : public nsIStreamProvider 1.112 +{ 1.113 +public: 1.114 + TestProvider(char *data); 1.115 + virtual ~TestProvider(); 1.116 + 1.117 + NS_DECL_ISUPPORTS 1.118 + NS_DECL_NSIREQUESTOBSERVER 1.119 + NS_DECL_NSISTREAMPROVIDER 1.120 + 1.121 +protected: 1.122 + char *mData; 1.123 + uint32_t mOffset; 1.124 + uint32_t mDataLen; 1.125 + uint32_t mRequestCount; 1.126 +}; 1.127 + 1.128 +NS_IMPL_ISUPPORTS(TestProvider, 1.129 + nsIStreamProvider, 1.130 + nsIRequestObserver) 1.131 + 1.132 +TestProvider::TestProvider(char *data) 1.133 +{ 1.134 + mData = data; 1.135 + mDataLen = strlen(data); 1.136 + mOffset = 0; 1.137 + mRequestCount = 0; 1.138 + LOG(("Constructing TestProvider [this=%p]\n", this)); 1.139 +} 1.140 + 1.141 +TestProvider::~TestProvider() 1.142 +{ 1.143 + LOG(("Destroying TestProvider [this=%p]\n", this)); 1.144 +} 1.145 + 1.146 +NS_IMETHODIMP 1.147 +TestProvider::OnStartRequest(nsIRequest* request, nsISupports* context) 1.148 +{ 1.149 + LOG(("TestProvider::OnStartRequest [this=%p]\n", this)); 1.150 + return NS_OK; 1.151 +} 1.152 + 1.153 +NS_IMETHODIMP 1.154 +TestProvider::OnStopRequest(nsIRequest* request, nsISupports* context, 1.155 + nsresult aStatus) 1.156 +{ 1.157 + LOG(("TestProvider::OnStopRequest [status=%x]\n", aStatus)); 1.158 + return NS_OK; 1.159 +} 1.160 + 1.161 +NS_IMETHODIMP 1.162 +TestProvider::OnDataWritable(nsIRequest *request, nsISupports *context, 1.163 + nsIOutputStream *output, uint32_t offset, uint32_t count) 1.164 +{ 1.165 + LOG(("TestProvider::OnDataWritable [offset=%u, count=%u]\n", offset, count)); 1.166 + 1.167 + // Stop at 5 requests 1.168 + if (mRequestCount == 5) 1.169 + return NS_BASE_STREAM_CLOSED; 1.170 + 1.171 + uint32_t writeCount, amount; 1.172 + amount = std::min(count, mDataLen - mOffset); 1.173 + nsresult rv = output->Write(mData + mOffset, amount, &writeCount); 1.174 + if (NS_SUCCEEDED(rv)) { 1.175 + printf("wrote %u bytes\n", writeCount); 1.176 + mOffset += writeCount; 1.177 + if (mOffset == mDataLen) { 1.178 + printf("done sending packet %u\n", mRequestCount); 1.179 + mOffset = 0; 1.180 + mRequestCount++; 1.181 + } 1.182 + } 1.183 + return NS_OK; 1.184 +} 1.185 + 1.186 +// 1.187 +//---------------------------------------------------------------------------- 1.188 +// Synchronous IO 1.189 +//---------------------------------------------------------------------------- 1.190 +// 1.191 +nsresult 1.192 +WriteRequest(nsIOutputStream *os, const char *request) 1.193 +{ 1.194 + LOG(("WriteRequest [request=%s]\n", request)); 1.195 + uint32_t n; 1.196 + return os->Write(request, strlen(request), &n); 1.197 +} 1.198 + 1.199 +nsresult 1.200 +ReadResponse(nsIInputStream *is) 1.201 +{ 1.202 + uint32_t bytesRead; 1.203 + char buf[2048]; 1.204 + do { 1.205 + is->Read(buf, sizeof(buf), &bytesRead); 1.206 + if (bytesRead > 0) 1.207 + fwrite(buf, 1, bytesRead, stdout); 1.208 + } while (bytesRead > 0); 1.209 + return NS_OK; 1.210 +} 1.211 + 1.212 +// 1.213 +//---------------------------------------------------------------------------- 1.214 +// Startup... 1.215 +//---------------------------------------------------------------------------- 1.216 +// 1.217 + 1.218 +void 1.219 +sighandler(int sig) 1.220 +{ 1.221 + LOG(("got signal: %d\n", sig)); 1.222 + NS_BREAK(); 1.223 +} 1.224 + 1.225 +void 1.226 +usage(char **argv) 1.227 +{ 1.228 + printf("usage: %s <host> <path>\n", argv[0]); 1.229 + exit(1); 1.230 +} 1.231 + 1.232 +int 1.233 +main(int argc, char* argv[]) 1.234 +{ 1.235 + nsresult rv; 1.236 + 1.237 + signal(SIGSEGV, sighandler); 1.238 + 1.239 +#if defined(PR_LOGGING) 1.240 + gTestSocketIOLog = PR_NewLogModule("TestSocketIO"); 1.241 +#endif 1.242 + 1.243 + if (argc < 3) 1.244 + usage(argv); 1.245 + 1.246 + char *hostName = argv[1]; 1.247 + char *fileName = argv[2]; 1.248 + int port = 80; 1.249 + 1.250 + // Create the Event Queue for this thread... 1.251 + nsCOMPtr<nsIEventQueueService> eventQService = 1.252 + do_GetService(kEventQueueServiceCID, &rv); 1.253 + if (NS_FAILED(rv)) { 1.254 + NS_WARNING("failed to create: event queue service!"); 1.255 + return rv; 1.256 + } 1.257 + 1.258 + rv = eventQService->CreateMonitoredThreadEventQueue(); 1.259 + if (NS_FAILED(rv)) { 1.260 + NS_WARNING("failed to create: thread event queue!"); 1.261 + return rv; 1.262 + } 1.263 + 1.264 + eventQService->GetThreadEventQueue(NS_CURRENT_THREAD, &gEventQ); 1.265 + 1.266 + // Create the Socket transport service... 1.267 + nsCOMPtr<nsISocketTransportService> sts = 1.268 + do_GetService(kSocketTransportServiceCID, &rv); 1.269 + if (NS_FAILED(rv)) { 1.270 + NS_WARNING("failed to create: socket transport service!"); 1.271 + return rv; 1.272 + } 1.273 + 1.274 + char *buffer = PR_smprintf("GET %s HTTP/1.1" CRLF 1.275 + "host: %s" CRLF 1.276 + "user-agent: Mozilla/5.0 (X11; N; Linux 2.2.16-22smp i686; en-US; m18) Gecko/20001220" CRLF 1.277 + "accept: */*" CRLF 1.278 + "accept-language: en" CRLF 1.279 + "accept-encoding: gzip,deflate,compress,identity" CRLF 1.280 + "keep-alive: 300" CRLF 1.281 + "connection: keep-alive" CRLF 1.282 + CRLF, 1.283 + fileName, hostName); 1.284 + LOG(("Request [\n%s]\n", buffer)); 1.285 + 1.286 + // Create the socket transport... 1.287 + nsCOMPtr<nsITransport> transport; 1.288 + rv = sts->CreateTransport(hostName, port, nullptr, -1, 0, 0, getter_AddRefs(transport)); 1.289 + if (NS_FAILED(rv)) { 1.290 + NS_WARNING("failed to create: socket transport!"); 1.291 + return rv; 1.292 + } 1.293 + 1.294 + gElapsedTime = PR_Now(); 1.295 + 1.296 + nsCOMPtr<nsIRequest> writeRequest, readRequest; 1.297 + 1.298 + rv = transport->AsyncWrite(new TestProvider(buffer), nullptr, 0, 0, 0, getter_AddRefs(writeRequest)); 1.299 + if (NS_FAILED(rv)) { 1.300 + NS_WARNING("failed calling: AsyncWrite!"); 1.301 + return rv; 1.302 + } 1.303 + rv = transport->AsyncRead(new TestListener(), nullptr, 0, 0, 0, getter_AddRefs(readRequest)); 1.304 + if (NS_FAILED(rv)) { 1.305 + NS_WARNING("failed calling: AsyncWrite!"); 1.306 + return rv; 1.307 + } 1.308 + 1.309 + // Enter the message pump 1.310 + while ( gKeepRunning ) { 1.311 + PLEvent *gEvent; 1.312 + gEventQ->WaitForEvent(&gEvent); 1.313 + gEventQ->HandleEvent(gEvent); 1.314 + } 1.315 + 1.316 + PRTime endTime; 1.317 + endTime = PR_Now(); 1.318 + LOG(("Elapsed time: %d\n", (int32_t)(endTime/1000UL - gElapsedTime/1000UL))); 1.319 + 1.320 + sts->Shutdown(); 1.321 + return 0; 1.322 +}