michael@0: #include "nsNetUtil.h" michael@0: #include "nsIEventQueueService.h" michael@0: #include "nsIServiceManager.h" michael@0: #include "nsIComponentRegistrar.h" michael@0: #include "nsIInterfaceRequestor.h" michael@0: #include "nsIInterfaceRequestorUtils.h" michael@0: #include "nsIProgressEventSink.h" michael@0: #include michael@0: michael@0: #define RETURN_IF_FAILED(rv, step) \ michael@0: PR_BEGIN_MACRO \ michael@0: if (NS_FAILED(rv)) { \ michael@0: printf(">>> %s failed: rv=%x\n", step, rv); \ michael@0: return rv;\ michael@0: } \ michael@0: PR_END_MACRO michael@0: michael@0: static NS_DEFINE_CID(kEventQueueServiceCID, NS_EVENTQUEUESERVICE_CID); michael@0: static nsIEventQueue* gEventQ = nullptr; michael@0: static bool gKeepRunning = true; michael@0: michael@0: //----------------------------------------------------------------------------- michael@0: // nsIStreamListener implementation michael@0: //----------------------------------------------------------------------------- michael@0: michael@0: class MyListener : public nsIStreamListener michael@0: { michael@0: public: michael@0: NS_DECL_ISUPPORTS michael@0: NS_DECL_NSIREQUESTOBSERVER michael@0: NS_DECL_NSISTREAMLISTENER michael@0: michael@0: MyListener() { } michael@0: virtual ~MyListener() {} michael@0: }; michael@0: michael@0: NS_IMPL_ISUPPORTS(MyListener, michael@0: nsIRequestObserver, michael@0: nsIStreamListener) michael@0: michael@0: NS_IMETHODIMP michael@0: MyListener::OnStartRequest(nsIRequest *req, nsISupports *ctxt) michael@0: { michael@0: printf(">>> OnStartRequest\n"); michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: MyListener::OnStopRequest(nsIRequest *req, nsISupports *ctxt, nsresult status) michael@0: { michael@0: printf(">>> OnStopRequest status=%x\n", status); michael@0: gKeepRunning = false; michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: MyListener::OnDataAvailable(nsIRequest *req, nsISupports *ctxt, michael@0: nsIInputStream *stream, michael@0: uint64_t offset, uint32_t count) michael@0: { michael@0: printf(">>> OnDataAvailable [count=%u]\n", count); michael@0: michael@0: char buf[256]; michael@0: nsresult rv; michael@0: uint32_t bytesRead=0; michael@0: michael@0: while (count) { michael@0: uint32_t amount = std::min(count, sizeof(buf)); michael@0: michael@0: rv = stream->Read(buf, amount, &bytesRead); michael@0: if (NS_FAILED(rv)) { michael@0: printf(">>> stream->Read failed with rv=%x\n", rv); michael@0: return rv; michael@0: } michael@0: michael@0: fwrite(buf, 1, bytesRead, stdout); michael@0: michael@0: count -= bytesRead; michael@0: } michael@0: return NS_OK; michael@0: } michael@0: michael@0: //----------------------------------------------------------------------------- michael@0: // NotificationCallbacks implementation michael@0: //----------------------------------------------------------------------------- michael@0: michael@0: class MyNotifications : public nsIInterfaceRequestor michael@0: , public nsIProgressEventSink michael@0: { michael@0: public: michael@0: NS_DECL_THREADSAFE_ISUPPORTS michael@0: NS_DECL_NSIINTERFACEREQUESTOR michael@0: NS_DECL_NSIPROGRESSEVENTSINK michael@0: michael@0: MyNotifications() { } michael@0: virtual ~MyNotifications() {} michael@0: }; michael@0: michael@0: NS_IMPL_ISUPPORTS(MyNotifications, michael@0: nsIInterfaceRequestor, michael@0: nsIProgressEventSink) michael@0: michael@0: NS_IMETHODIMP michael@0: MyNotifications::GetInterface(const nsIID &iid, void **result) michael@0: { michael@0: return QueryInterface(iid, result); michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: MyNotifications::OnStatus(nsIRequest *req, nsISupports *ctx, michael@0: nsresult status, const char16_t *statusText) michael@0: { michael@0: printf("status: %x\n", status); michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: MyNotifications::OnProgress(nsIRequest *req, nsISupports *ctx, michael@0: uint64_t progress, uint64_t progressMax) michael@0: { michael@0: printf("progress: %llu/%llu\n", progress, progressMax); michael@0: return NS_OK; michael@0: } michael@0: michael@0: //----------------------------------------------------------------------------- michael@0: // main, etc.. michael@0: //----------------------------------------------------------------------------- michael@0: michael@0: michael@0: int main(int argc, char **argv) michael@0: { michael@0: nsresult rv; michael@0: michael@0: if (argc == 1) { michael@0: printf("usage: TestHttp \n"); michael@0: return -1; michael@0: } michael@0: { michael@0: nsCOMPtr servMan; michael@0: NS_InitXPCOM2(getter_AddRefs(servMan), nullptr, nullptr); michael@0: nsCOMPtr registrar = do_QueryInterface(servMan); michael@0: NS_ASSERTION(registrar, "Null nsIComponentRegistrar"); michael@0: if (registrar) michael@0: registrar->AutoRegister(nullptr); michael@0: michael@0: // Create the Event Queue for this thread... michael@0: nsCOMPtr eqs = michael@0: do_GetService(kEventQueueServiceCID, &rv); michael@0: RETURN_IF_FAILED(rv, "do_GetService(EventQueueService)"); michael@0: michael@0: rv = eqs->CreateMonitoredThreadEventQueue(); michael@0: RETURN_IF_FAILED(rv, "CreateMonitoredThreadEventQueue"); michael@0: michael@0: rv = eqs->GetThreadEventQueue(NS_CURRENT_THREAD, &gEventQ); michael@0: RETURN_IF_FAILED(rv, "GetThreadEventQueue"); michael@0: michael@0: nsCOMPtr uri; michael@0: nsCOMPtr chan; michael@0: nsCOMPtr listener = new MyListener(); michael@0: nsCOMPtr callbacks = new MyNotifications(); michael@0: michael@0: rv = NS_NewURI(getter_AddRefs(uri), argv[1]); michael@0: RETURN_IF_FAILED(rv, "NS_NewURI"); michael@0: michael@0: rv = NS_NewChannel(getter_AddRefs(chan), uri, nullptr, nullptr, callbacks); michael@0: RETURN_IF_FAILED(rv, "NS_OpenURI"); michael@0: michael@0: rv = chan->AsyncOpen(listener, nullptr); michael@0: RETURN_IF_FAILED(rv, "AsyncOpen"); michael@0: michael@0: while (gKeepRunning) michael@0: gEventQ->ProcessPendingEvents(); michael@0: michael@0: printf(">>> done\n"); michael@0: } // this scopes the nsCOMPtrs michael@0: // no nsCOMPtrs are allowed to be alive when you call NS_ShutdownXPCOM michael@0: rv = NS_ShutdownXPCOM(nullptr); michael@0: NS_ASSERTION(NS_SUCCEEDED(rv), "NS_ShutdownXPCOM failed"); michael@0: return 0; michael@0: }