netwerk/test/TestSocketIO.cpp

Wed, 31 Dec 2014 06:55:46 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:55:46 +0100
changeset 1
ca08bd8f51b2
permissions
-rw-r--r--

Added tag TORBROWSER_REPLICA for changeset 6474c204b198

     1 /* -*- Mode: C++; tab-width: 2; 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/. */
     5 #include <stdio.h>
     6 #include <signal.h>
     8 #ifdef WIN32
     9 #include <windows.h>
    10 #endif
    12 #include "nspr.h"
    13 #include "nscore.h"
    14 #include "nsISocketTransportService.h"
    15 #include "nsIEventQueueService.h"
    16 #include "nsIServiceManager.h"
    17 #include "nsITransport.h"
    18 #include "nsIRequest.h"
    19 #include "nsIStreamProvider.h"
    20 #include "nsIStreamListener.h"
    21 #include "nsIPipe.h"
    22 #include "nsIOutputStream.h"
    23 #include "nsIInputStream.h"
    24 #include "nsCRT.h"
    25 #include "nsCOMPtr.h"
    26 #include "nsIByteArrayInputStream.h"
    28 #if defined(PR_LOGGING)
    29 static PRLogModuleInfo *gTestSocketIOLog;
    30 #define LOG(args) PR_LOG(gTestSocketIOLog, PR_LOG_DEBUG, args)
    31 #else
    32 #define LOG(args)
    33 #endif
    35 static NS_DEFINE_CID(kSocketTransportServiceCID, NS_SOCKETTRANSPORTSERVICE_CID);
    36 static NS_DEFINE_CID(kEventQueueServiceCID, NS_EVENTQUEUESERVICE_CID);
    38 static PRTime gElapsedTime;
    39 static int gKeepRunning = 1;
    40 static nsIEventQueue* gEventQ = nullptr;
    42 //
    43 //----------------------------------------------------------------------------
    44 // Test Listener
    45 //----------------------------------------------------------------------------
    46 //
    48 class TestListener : public nsIStreamListener
    49 {
    50 public:
    51     TestListener() {}
    52     virtual ~TestListener() {}
    54     NS_DECL_ISUPPORTS
    55     NS_DECL_NSIREQUESTOBSERVER
    56     NS_DECL_NSISTREAMLISTENER
    57 };
    59 NS_IMPL_ISUPPORTS(TestListener,
    60                   nsIRequestObserver,
    61                   nsIStreamListener);
    63 NS_IMETHODIMP
    64 TestListener::OnStartRequest(nsIRequest* request, nsISupports* context)
    65 {
    66     LOG(("TestListener::OnStartRequest\n"));
    67     return NS_OK;
    68 }
    70 NS_IMETHODIMP
    71 TestListener::OnDataAvailable(nsIRequest* request,
    72                               nsISupports* context,
    73                               nsIInputStream *aIStream, 
    74                               uint32_t aSourceOffset,
    75                               uint32_t aLength)
    76 {
    77     LOG(("TestListener::OnDataAvailable [offset=%u length=%u]\n",
    78         aSourceOffset, aLength));
    79     char buf[1025];
    80     uint32_t amt;
    81     while (1) {
    82         aIStream->Read(buf, 1024, &amt);
    83         if (amt == 0)
    84             break;
    85         buf[amt] = '\0';
    86         puts(buf);
    87     }
    88     return NS_OK;
    89 }
    91 NS_IMETHODIMP
    92 TestListener::OnStopRequest(nsIRequest* request, nsISupports* context,
    93                             nsresult aStatus)
    94 {
    95     LOG(("TestListener::OnStopRequest [aStatus=%x]\n", aStatus));
    96     gKeepRunning = 0;
    97     return NS_OK;
    98 }
   100 //
   101 //----------------------------------------------------------------------------
   102 // Test Provider
   103 //----------------------------------------------------------------------------
   104 //
   106 class TestProvider : public nsIStreamProvider
   107 {
   108 public:
   109     TestProvider(char *data);
   110     virtual ~TestProvider();
   112     NS_DECL_ISUPPORTS
   113     NS_DECL_NSIREQUESTOBSERVER
   114     NS_DECL_NSISTREAMPROVIDER
   116 protected:
   117     nsCOMPtr<nsIByteArrayInputStream> mData;
   118 };
   120 NS_IMPL_ISUPPORTS(TestProvider,
   121                   nsIStreamProvider,
   122                   nsIRequestObserver)
   124 TestProvider::TestProvider(char *data)
   125 {
   126     NS_NewByteArrayInputStream(getter_AddRefs(mData), data, strlen(data));
   127     LOG(("Constructing TestProvider [this=%p]\n", this));
   128 }
   130 TestProvider::~TestProvider()
   131 {
   132     LOG(("Destroying TestProvider [this=%p]\n", this));
   133 }
   135 NS_IMETHODIMP
   136 TestProvider::OnStartRequest(nsIRequest* request, nsISupports* context)
   137 {
   138     LOG(("TestProvider::OnStartRequest [this=%p]\n", this));
   139     return NS_OK;
   140 }
   142 NS_IMETHODIMP
   143 TestProvider::OnStopRequest(nsIRequest* request, nsISupports* context,
   144                             nsresult aStatus)
   145 {
   146     LOG(("TestProvider::OnStopRequest [status=%x]\n", aStatus));
   148     nsCOMPtr<nsIStreamListener> listener = do_QueryInterface(new TestListener());
   150     if (NS_SUCCEEDED(aStatus)) {
   151         nsCOMPtr<nsITransportRequest> treq = do_QueryInterface(request);
   152         nsCOMPtr<nsITransport> transport;
   153         treq->GetTransport(getter_AddRefs(transport));
   154         if (transport) {
   155             nsCOMPtr<nsIRequest> readRequest;
   156             transport->AsyncRead(listener, nullptr, 0, 0, 0, getter_AddRefs(readRequest));
   157         }
   158     } else
   159         gKeepRunning = 0;
   161     return NS_OK;
   162 }
   164 NS_IMETHODIMP
   165 TestProvider::OnDataWritable(nsIRequest *request, nsISupports *context,
   166                              nsIOutputStream *output, uint32_t offset, uint32_t count)
   167 {
   168     LOG(("TestProvider::OnDataWritable [offset=%u, count=%u]\n", offset, count));
   169     uint32_t writeCount;
   170     nsresult rv = output->WriteFrom(mData, count, &writeCount);
   171     // Zero bytes written on success indicates EOF
   172     if (NS_SUCCEEDED(rv) && (writeCount == 0))
   173         return NS_BASE_STREAM_CLOSED;
   174     return rv;
   175 }
   177 //
   178 //----------------------------------------------------------------------------
   179 // Synchronous IO
   180 //----------------------------------------------------------------------------
   181 //
   182 nsresult
   183 WriteRequest(nsIOutputStream *os, const char *request)
   184 {
   185     LOG(("WriteRequest [request=%s]\n", request));
   186     uint32_t n;
   187     return os->Write(request, strlen(request), &n);
   188 }
   190 nsresult
   191 ReadResponse(nsIInputStream *is)
   192 {
   193     uint32_t bytesRead;
   194     char buf[2048];
   195     do {
   196         is->Read(buf, sizeof(buf), &bytesRead);
   197         if (bytesRead > 0)
   198             fwrite(buf, 1, bytesRead, stdout);
   199     } while (bytesRead > 0);
   200     return NS_OK;
   201 }
   203 //
   204 //----------------------------------------------------------------------------
   205 // Startup...
   206 //----------------------------------------------------------------------------
   207 //
   209 void
   210 sighandler(int sig)
   211 {
   212     LOG(("got signal: %d\n", sig));
   213     NS_BREAK();
   214 }
   216 void
   217 usage(char **argv)
   218 {
   219     printf("usage: %s [-sync] <host> <path>\n", argv[0]);
   220     exit(1);
   221 }
   223 int
   224 main(int argc, char* argv[])
   225 {
   226     nsresult rv;
   228     signal(SIGSEGV, sighandler);
   230 #if defined(PR_LOGGING)
   231     gTestSocketIOLog = PR_NewLogModule("TestSocketIO");
   232 #endif
   234     if (argc < 3)
   235         usage(argv);
   237     int i=0;
   238     bool sync = false;
   239     if (nsCRT::strcasecmp(argv[1], "-sync") == 0) {
   240         if (argc < 4)
   241             usage(argv);
   242         sync = true;
   243         i = 1;
   244     }
   246     char *hostName = argv[1+i];
   247     char *fileName = argv[2+i];
   248     int port = 80;
   250     // Create the Event Queue for this thread...
   251     nsCOMPtr<nsIEventQueueService> eventQService = 
   252              do_GetService(kEventQueueServiceCID, &rv);
   253     if (NS_FAILED(rv)) {
   254         NS_WARNING("failed to create: event queue service!");
   255         return rv;
   256     }
   258     rv = eventQService->CreateMonitoredThreadEventQueue();
   259     if (NS_FAILED(rv)) {
   260         NS_WARNING("failed to create: thread event queue!");
   261         return rv;
   262     }
   264     eventQService->GetThreadEventQueue(NS_CURRENT_THREAD, &gEventQ);
   266     // Create the Socket transport service...
   267     nsCOMPtr<nsISocketTransportService> sts = 
   268              do_GetService(kSocketTransportServiceCID, &rv);
   269     if (NS_FAILED(rv)) {
   270         NS_WARNING("failed to create: socket transport service!");
   271         return rv;
   272     }
   274     char *buffer = PR_smprintf("GET %s HTTP/1.1" CRLF
   275                                "host: %s" CRLF
   276                                "user-agent: Mozilla/5.0 (X11; N; Linux 2.2.16-22smp i686; en-US; m18) Gecko/20001220" CRLF
   277                                "accept: */*" CRLF
   278                                "accept-language: en" CRLF
   279                                "accept-encoding: gzip,deflate,compress,identity" CRLF
   280                                "keep-alive: 300" CRLF
   281                                "connection: keep-alive" CRLF
   282                                 CRLF,
   283                                 fileName, hostName);
   284     LOG(("Request [\n%s]\n", buffer));
   286     // Create the socket transport...
   287     nsCOMPtr<nsITransport> transport;
   288     rv = sts->CreateTransport(hostName, port, nullptr, 0, 0, getter_AddRefs(transport));
   289     if (NS_FAILED(rv)) {
   290         NS_WARNING("failed to create: socket transport!");
   291         return rv;
   292     }
   294     gElapsedTime = PR_Now();
   296     if (!sync) {
   297         nsCOMPtr<nsIRequest> request;
   298         rv = transport->AsyncWrite(new TestProvider(buffer), nullptr, 0, 0, 0, getter_AddRefs(request));
   299         if (NS_FAILED(rv)) {
   300             NS_WARNING("failed calling: AsyncWrite!");
   301             return rv;
   302         }
   304         // Enter the message pump to allow the URL load to proceed.
   305         while ( gKeepRunning ) {
   306             PLEvent *gEvent;
   307             gEventQ->WaitForEvent(&gEvent);
   308             gEventQ->HandleEvent(gEvent);
   309         }
   310     }
   311     else {
   312         // synchronous write
   313         {
   314             nsCOMPtr<nsIOutputStream> os;
   315             rv = transport->OpenOutputStream(0, 0, 0, getter_AddRefs(os));
   316             if (NS_FAILED(rv)) {
   317                 LOG(("OpenOutputStream failed [rv=%x]\n", rv));
   318                 return rv;
   319             }
   320             rv = WriteRequest(os, buffer);
   321             if (NS_FAILED(rv)) {
   322                 LOG(("WriteRequest failed [rv=%x]\n", rv));
   323                 return rv;
   324             }
   325         }
   326         // synchronous read
   327         {
   328             nsCOMPtr<nsIInputStream> is;
   329             rv = transport->OpenInputStream(0, 0, 0, getter_AddRefs(is));
   330             if (NS_FAILED(rv)) {
   331                 LOG(("OpenInputStream failed [rv=%x]\n", rv));
   332                 return rv;
   333             }
   334             rv = ReadResponse(is);
   335             if (NS_FAILED(rv)) {
   336                 LOG(("ReadResponse failed [rv=%x]\n", rv));
   337                 return rv;
   338             }
   339         }
   340     }
   342     PRTime endTime; 
   343     endTime = PR_Now();
   344     LOG(("Elapsed time: %d\n", (int32_t)(endTime/1000UL - gElapsedTime/1000UL)));
   346     sts->Shutdown();
   347     return 0;
   348 }

mercurial