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