Back to index

lightning-sunbird  0.9+nobinonly
nsHTTPSOAPTransport.cpp
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
00002 /* ***** BEGIN LICENSE BLOCK *****
00003  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00004  *
00005  * The contents of this file are subject to the Mozilla Public License Version
00006  * 1.1 (the "License"); you may not use this file except in compliance with
00007  * the License. You may obtain a copy of the License at
00008  * http://www.mozilla.org/MPL/
00009  *
00010  * Software distributed under the License is distributed on an "AS IS" basis,
00011  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00012  * for the specific language governing rights and limitations under the
00013  * License.
00014  *
00015  * The Original Code is mozilla.org code.
00016  *
00017  * The Initial Developer of the Original Code is
00018  * Netscape Communications Corporation.
00019  * Portions created by the Initial Developer are Copyright (C) 2001
00020  * the Initial Developer. All Rights Reserved.
00021  *
00022  * Contributor(s):
00023  *
00024  * Alternatively, the contents of this file may be used under the terms of
00025  * either the GNU General Public License Version 2 or later (the "GPL"), or
00026  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00027  * in which case the provisions of the GPL or the LGPL are applicable instead
00028  * of those above. If you wish to allow use of your version of this file only
00029  * under the terms of either the GPL or the LGPL, and not to allow others to
00030  * use your version of this file under the terms of the MPL, indicate your
00031  * decision by deleting the provisions above and replace them with the notice
00032  * and other provisions required by the GPL or the LGPL. If you do not delete
00033  * the provisions above, a recipient may use your version of this file under
00034  * the terms of any one of the MPL, the GPL or the LGPL.
00035  *
00036  * ***** END LICENSE BLOCK ***** */
00037 
00038 #include "nsXPIDLString.h"
00039 #include "nsHTTPSOAPTransport.h"
00040 #include "nsIComponentManager.h"
00041 #include "nsIDOMDocument.h"
00042 #include "nsIDOMText.h"
00043 #include "nsIURI.h"
00044 #include "nsNetUtil.h"
00045 #include "nsIScriptSecurityManager.h"
00046 #include "nsIPrincipal.h"
00047 #include "nsIVariant.h"
00048 #include "nsString.h"
00049 #include "nsSOAPUtils.h"
00050 #include "nsSOAPCall.h"
00051 #include "nsSOAPException.h"
00052 #include "nsSOAPResponse.h"
00053 #include "nsISOAPCallCompletion.h"
00054 #include "nsIDOMEventTarget.h"
00055 #include "nsIDOMSerializer.h"
00056 #include "nsIWebScriptsAccessService.h"
00057 #include "nsMemory.h"
00058 #include "nsIDocument.h"
00059 
00060 nsHTTPSOAPTransport::nsHTTPSOAPTransport()
00061 {
00062 }
00063 
00064 nsHTTPSOAPTransport::~nsHTTPSOAPTransport()
00065 {
00066 }
00067 
00068 NS_IMPL_ISUPPORTS1_CI(nsHTTPSOAPTransport, nsISOAPTransport)
00069 #ifdef DEBUG
00070 #define DEBUG_DUMP_DOCUMENT(message,doc) \
00071   { \
00072           nsresult rcc;\
00073           nsAutoString serial;\
00074           nsCOMPtr<nsIDOMSerializer> serializer(do_CreateInstance(NS_XMLSERIALIZER_CONTRACTID, &rcc));\
00075           if (NS_FAILED(rcc)) return rcc;  \
00076           rcc = serializer->SerializeToString(doc, serial);\
00077           if (NS_FAILED(rcc)) return rcc;\
00078           printf(message ":\n%s\n", NS_ConvertUTF16toUTF8(serial).get());\
00079   }
00080 //  Availble from the debugger...
00081 nsresult DebugPrintDOM(nsIDOMNode * node)
00082 {
00083   DEBUG_DUMP_DOCUMENT("DOM", node) return NS_OK;
00084 }
00085 #else
00086 #define DEBUG_DUMP_DOCUMENT(message,doc)
00087 #endif
00088 
00097 static 
00098 nsresult ChangePrincipal(nsIDOMDocument* aDocument)
00099 {
00100   if (!aDocument)
00101     return NS_OK;
00102 
00103   nsresult rv;
00104   nsCOMPtr<nsIScriptSecurityManager> secMgr = 
00105     do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID, &rv);
00106   NS_ENSURE_SUCCESS(rv, rv);
00107   
00108   nsCOMPtr<nsIDocument> targetDoc(do_QueryInterface(aDocument, &rv));
00109   NS_ENSURE_SUCCESS(rv, rv);
00110   
00111   rv = secMgr->CheckSameOrigin(nsnull, targetDoc->GetDocumentURI());
00112   // change the principal only if the script security 
00113   // manager has denied access.
00114   if (NS_FAILED(rv)) {
00115     nsCOMPtr<nsIPrincipal> subjectPrincipal;
00116     rv = secMgr->GetSubjectPrincipal(getter_AddRefs(subjectPrincipal));
00117     if (NS_SUCCEEDED(rv))
00118       targetDoc->SetPrincipal(subjectPrincipal);
00119   }
00120   return rv;
00121 }
00122 
00128 static nsresult GetTransportURI(nsISOAPCall * aCall, nsAString & aURI)
00129 {
00130   nsresult rc = aCall->GetTransportURI(aURI);
00131   if (NS_FAILED(rc))
00132     return rc;
00133   
00134   // Create a new URI
00135   nsCOMPtr<nsIURI> uri;
00136   rc = NS_NewURI(getter_AddRefs(uri), aURI, nsnull);
00137   if (NS_FAILED(rc)) 
00138     return rc;
00139 
00140   nsCOMPtr<nsIWebScriptsAccessService> wsa_service = 
00141       do_GetService(NS_WEBSCRIPTSACCESSSERVICE_CONTRACTID, &rc);
00142   if (NS_FAILED(rc)) 
00143     return rc;
00144  
00145   PRBool safe = PR_FALSE;
00146   rc = aCall->GetVerifySourceHeader(&safe);
00147   if (NS_FAILED(rc)) 
00148     return rc;
00149 
00150   nsCOMPtr<nsIScriptSecurityManager> secMan;
00151   PRBool accessGranted;
00152   if (!safe) {
00153     rc = wsa_service->CanAccess(uri, NS_LITERAL_STRING("soap"), &accessGranted);
00154     if (NS_FAILED(rc))
00155       return rc;
00156     if (!accessGranted) {
00157       // Get security manager, check to see if we're allowed to call this URI.
00158       secMan = do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID, &rc);
00159       if (NS_FAILED(rc)) 
00160         return rc;
00161       if (NS_FAILED(secMan->CheckConnect(nsnull, uri, "SOAPCall", "invoke")))
00162         return SOAP_EXCEPTION(NS_ERROR_FAILURE,
00163                               "SOAP_INVOKE_DISABLED", 
00164                               "SOAPCall.invoke not enabled by client");
00165     }
00166   }
00167   else {
00168     // Get security manager, check to see if we're allowed to call this URI.
00169     secMan = do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID, &rc);
00170     if (NS_FAILED(rc))
00171       return rc;
00172     rc = wsa_service->CanAccess(uri, NS_LITERAL_STRING("soapv"), &accessGranted);
00173     if (NS_FAILED(rc))
00174       return rc;
00175     if (!accessGranted) {
00176       if (NS_FAILED(secMan->CheckConnect(nsnull, uri, "SOAPCall", "invokeVerifySourceHeader")))
00177         return SOAP_EXCEPTION(NS_ERROR_FAILURE,
00178                               "SOAP_INVOKE_VERIFY_DISABLED", 
00179                               "SOAPCall.invokeVerifySourceHeader not enabled by client");
00180     }
00181 
00182     nsAutoString sourceURI;
00183 
00184     {
00185 
00186       nsCOMPtr<nsIPrincipal> principal;
00187       rc = secMan->GetSubjectPrincipal(getter_AddRefs(principal));
00188       if (NS_FAILED(rc)) 
00189         return rc;
00190       if (!principal) {
00191         return SOAP_EXCEPTION(NS_ERROR_FAILURE,
00192                               "SOAP_INVOKE_VERIFY_PRINCIPAL", 
00193                               "Source-verified message cannot be sent without principal.");
00194       }
00195 
00196       nsCOMPtr<nsIURI> uri;
00197       principal->GetURI(getter_AddRefs(uri));
00198       if (!uri) {
00199         return SOAP_EXCEPTION(NS_ERROR_FAILURE,
00200                               "SOAP_INVOKE_VERIFY_URI", 
00201                               "Source-verified message cannot be sent without URI.");
00202       }
00203 
00204       nsCAutoString spec;
00205       rc = uri->GetSpec(spec);
00206       if (NS_FAILED(rc)) 
00207         return rc;
00208       CopyASCIItoUCS2(spec, sourceURI);
00209     }
00210 
00211 //  Adding a header to tell the server that it must understand and verify the source of the call
00212 
00213     nsCOMPtr<nsIDOMElement> element;
00214     rc = aCall->GetHeader(getter_AddRefs(element));
00215     if (NS_FAILED(rc)) 
00216       return rc;
00217     if (!element)
00218       return SOAP_EXCEPTION(NS_ERROR_FAILURE,"SOAP_INVOKE_VERIFY_HEADER", "Source-verified message cannot be sent without a header.");
00219     //  Node ignored on remove / append calls
00220     nsCOMPtr<nsIDOMNode> ignore;
00221     //  Remove any existing elements that may conflict with this verifySource identification
00222     nsCOMPtr<nsIDOMElement> verifySource;
00223     for (;;) {
00224       nsSOAPUtils::GetSpecificChildElement(nsnull, element, gSOAPStrings->kVerifySourceNamespaceURI, 
00225         gSOAPStrings->kVerifySourceHeader, getter_AddRefs(verifySource));
00226       if (verifySource) {
00227         rc = element->RemoveChild(verifySource, getter_AddRefs(ignore));
00228         if (NS_FAILED(rc))
00229           return rc;
00230       }
00231       else
00232        break;
00233     }
00234     //  Document as factory
00235     nsCOMPtr<nsIDOMDocument> document;
00236     rc = element->GetOwnerDocument(getter_AddRefs(document));
00237     if (NS_FAILED(rc)) 
00238       return rc;
00239     //  Proper version to use of SOAP
00240     PRUint16 version;
00241     rc = aCall->GetVersion(&version);
00242     if (NS_FAILED(rc)) 
00243       return rc;
00244     //  Proper schema to use for types
00245     nsAutoString XSURI;
00246     nsAutoString XSIURI;
00247     nsAutoString SOAPEncURI;
00248     if (version == nsISOAPMessage::VERSION_1_1) {
00249       XSURI.Assign(gSOAPStrings->kXSURI1999);
00250       XSIURI.Assign(gSOAPStrings->kXSIURI1999);
00251       SOAPEncURI.Assign(gSOAPStrings->kSOAPEncURI11);
00252     }
00253     else {
00254       XSURI.Assign(gSOAPStrings->kXSURI);
00255       XSIURI.Assign(gSOAPStrings->kXSIURI);
00256       SOAPEncURI.Assign(gSOAPStrings->kSOAPEncURI);
00257     }
00258     //  Create the header and append it with mustUnderstand and normal encoding.
00259     rc = document->CreateElementNS(gSOAPStrings->kVerifySourceNamespaceURI, 
00260       gSOAPStrings->kVerifySourceHeader, 
00261       getter_AddRefs(verifySource));
00262     if (NS_FAILED(rc)) 
00263       return rc;
00264     rc = element->AppendChild(verifySource, getter_AddRefs(ignore));
00265     if (NS_FAILED(rc)) 
00266       return rc;
00267     rc = verifySource->SetAttributeNS(*gSOAPStrings->kSOAPEnvURI[version],
00268       gSOAPStrings->kMustUnderstandAttribute,gSOAPStrings->kTrueA);// mustUnderstand
00269     if (NS_FAILED(rc)) 
00270       return rc;
00271     rc = verifySource->SetAttributeNS(*gSOAPStrings->kSOAPEnvURI[version], 
00272       gSOAPStrings->kEncodingStyleAttribute, SOAPEncURI);// 1.2 encoding
00273     if (NS_FAILED(rc)) 
00274       return rc;
00275 
00276     //  Prefixed string for xsi:string
00277     nsAutoString stringType;
00278     {
00279       nsAutoString prefix;
00280       rc = nsSOAPUtils::MakeNamespacePrefix(nsnull, verifySource, XSURI, stringType);
00281       if (NS_FAILED(rc)) 
00282         return rc;
00283       stringType.Append(gSOAPStrings->kQualifiedSeparator);
00284       stringType.AppendLiteral("anyURI");
00285     }
00286 
00287     //  If it is available, add the sourceURI 
00288     if (!sourceURI.IsEmpty()) {
00289       rc = document->CreateElementNS(gSOAPStrings->kVerifySourceNamespaceURI,
00290         gSOAPStrings->kVerifySourceURI,getter_AddRefs(element));
00291       if (NS_FAILED(rc)) 
00292         return rc;
00293       rc = verifySource->AppendChild(element, getter_AddRefs(ignore));
00294       if (NS_FAILED(rc)) 
00295         return rc;
00296       rc = element->SetAttributeNS(XSIURI,
00297         gSOAPStrings->kXSITypeAttribute,stringType);
00298       if (NS_FAILED(rc)) 
00299         return rc;
00300       nsCOMPtr<nsIDOMText> text;
00301       rc = document->CreateTextNode(sourceURI, getter_AddRefs(text));
00302       if (NS_FAILED(rc)) 
00303         return rc;
00304       rc = element->AppendChild(text, getter_AddRefs(ignore));
00305       if (NS_FAILED(rc)) 
00306         return rc;
00307     }
00308   }
00309   return NS_OK;
00310 }
00311 
00312 nsresult // static
00313 nsHTTPSOAPTransport::SetupRequest(nsISOAPCall* aCall, PRBool async,
00314                                   nsIXMLHttpRequest** ret)
00315 {
00316   nsresult rv;
00317   nsCOMPtr<nsIXMLHttpRequest> request = do_CreateInstance(NS_XMLHTTPREQUEST_CONTRACTID, &rv);
00318   if (NS_FAILED(rv))
00319     return rv;
00320 
00321   nsAutoString uri;
00322   rv = GetTransportURI(aCall, uri);
00323   if (NS_FAILED(rv))
00324     return rv;
00325   if (AStringIsNull(uri))
00326     return SOAP_EXCEPTION(NS_ERROR_NOT_INITIALIZED,"SOAP_TRANSPORT_URI", "No transport URI was specified.");
00327 
00328   rv = request->OverrideMimeType(NS_LITERAL_CSTRING("application/xml"));
00329   if (NS_FAILED(rv))
00330     return rv;
00331 
00332   const nsAString& empty = EmptyString();
00333   rv = request->OpenRequest(NS_LITERAL_CSTRING("POST"),
00334                             NS_ConvertUTF16toUTF8(uri), async, empty, empty);
00335   if (NS_FAILED(rv))
00336     return rv;
00337 
00338   nsAutoString action;
00339   rv = aCall->GetActionURI(action);
00340   if (NS_FAILED(rv))
00341     return rv;
00342 
00343   // nsXMLHttpRequest sends nsIDOMDocument payloads encoded as UTF-8,
00344   // but it doesn't say so in the Content-Type header. For SOAP
00345   // requests, we prefer to make this explicit. Some implementations
00346   // rely on this.
00347 
00348   // XXX : Use application/soap+xml for SOAP 1.2 once it gets
00349   // registered by IANA.
00350   rv = request->SetRequestHeader(NS_LITERAL_CSTRING("Content-Type"),
00351                                  NS_LITERAL_CSTRING("text/xml; charset=UTF-8"));
00352   if (NS_FAILED(rv))
00353     return rv;
00354 
00355   // Apache Axis web services WSDL files say to set soapAction to "" and require it to be sent.  
00356   // So only check if its not void instead of using AStringIsNull.
00357   if (!action.IsVoid()) {
00358 
00359     //XXXdoron necko doesn't allow empty header values, so set it to " "
00360     if (action.IsEmpty())
00361       action.AssignLiteral(" ");
00362 
00363     rv = request->SetRequestHeader(NS_LITERAL_CSTRING("SOAPAction"),
00364                                    NS_ConvertUTF16toUTF8(action));
00365     if (NS_FAILED(rv))
00366       return rv;
00367   }
00368 
00369 
00370   NS_ADDREF(*ret = request);
00371 
00372   return NS_OK;
00373 }
00374 
00375 /* void syncCall (in nsISOAPCall aCall, in nsISOAPResponse aResponse); */
00376 NS_IMETHODIMP 
00377 nsHTTPSOAPTransport::SyncCall(nsISOAPCall * aCall, nsISOAPResponse * aResponse)
00378 {
00379   NS_ENSURE_ARG(aCall);
00380 
00381   nsCOMPtr<nsIDOMDocument> messageDocument;
00382   nsresult rv = aCall->GetMessage(getter_AddRefs(messageDocument));
00383   if (NS_FAILED(rv))
00384     return rv;
00385   if (!messageDocument)
00386     return SOAP_EXCEPTION(NS_ERROR_NOT_INITIALIZED,"SOAP_MESSAGE_DOCUMENT", "No message document is present.");
00387   DEBUG_DUMP_DOCUMENT("Synchronous Request", messageDocument)
00388 
00389   nsCOMPtr<nsIXMLHttpRequest> request;
00390   rv = SetupRequest(aCall, PR_FALSE, getter_AddRefs(request));
00391   if (NS_FAILED(rv))
00392     return rv;
00393 
00394   nsCOMPtr<nsIWritableVariant> variant =
00395       do_CreateInstance(NS_VARIANT_CONTRACTID, &rv);
00396   if (NS_FAILED(rv))
00397     return rv;
00398 
00399   rv = variant->SetAsInterface(NS_GET_IID(nsIDOMDocument),
00400                                messageDocument);
00401   if (NS_FAILED(rv))
00402     return rv;
00403 
00404 
00405   rv = request->Send(variant);
00406   if (NS_FAILED(rv))
00407     return rv;
00408 
00409 #if 0
00410   PRUint32 status;
00411   rv = request->GetStatus(&status);
00412   if (NS_SUCCEEDED(rv) && (status < 200 || status >= 300))
00413     rv = NS_ERROR_FAILURE;
00414   if (NS_FAILED(rv))
00415     return rv;
00416 #endif
00417 
00418   if (aResponse) {
00419     nsCOMPtr<nsIDOMDocument> response;
00420     rv = request->GetResponseXML(getter_AddRefs(response));
00421     if (NS_FAILED(rv))
00422       return rv;
00423     if (response) {
00424     DEBUG_DUMP_DOCUMENT("Asynchronous Response", response)}
00425     rv = aResponse->SetMessage(response);
00426     if (NS_FAILED(rv))
00427       return rv;
00428   }
00429 
00430   return NS_OK;
00431 }
00432 
00433 NS_IMPL_ISUPPORTS2_CI(nsHTTPSOAPTransportCompletion, nsIDOMEventListener,
00434                       nsISOAPCallCompletion)
00435     nsHTTPSOAPTransportCompletion::nsHTTPSOAPTransportCompletion()
00436 {
00437 }
00438 
00439 nsHTTPSOAPTransportCompletion::nsHTTPSOAPTransportCompletion(nsISOAPCall * call, nsISOAPResponse * response, nsIXMLHttpRequest * request, nsISOAPResponseListener * listener) :
00440 mCall(call), mResponse(response), mRequest(request), mListener(listener)
00441 {
00442 }
00443 
00444 nsHTTPSOAPTransportCompletion::~nsHTTPSOAPTransportCompletion()
00445 {
00446 }
00447 
00448 /* readonly attribute nsISOAPCall call; */
00449 NS_IMETHODIMP nsHTTPSOAPTransportCompletion::GetCall(nsISOAPCall * *aCall)
00450 {
00451   NS_ENSURE_ARG(aCall);
00452   *aCall = mCall;
00453   NS_IF_ADDREF(*aCall);
00454   return NS_OK;
00455 }
00456 
00457 /* readonly attribute nsISOAPResponse response; */
00458 NS_IMETHODIMP
00459     nsHTTPSOAPTransportCompletion::GetResponse(nsISOAPResponse *
00460                                                *aResponse)
00461 {
00462   NS_ENSURE_ARG(aResponse);
00463   *aResponse =
00464       mRequest ? nsnull : mResponse.get();
00465   NS_IF_ADDREF(*aResponse);
00466   return NS_OK;
00467 }
00468 
00469 /* readonly attribute nsISOAPResponseListener listener; */
00470 NS_IMETHODIMP
00471     nsHTTPSOAPTransportCompletion::GetListener(nsISOAPResponseListener *
00472                                                *aListener)
00473 {
00474   NS_ENSURE_ARG(aListener);
00475   *aListener = mListener;
00476   NS_IF_ADDREF(*aListener);
00477   return NS_OK;
00478 }
00479 
00480 /* readonly attribute boolean isComplete; */
00481 NS_IMETHODIMP
00482     nsHTTPSOAPTransportCompletion::GetIsComplete(PRBool * aIsComplete)
00483 {
00484   NS_ENSURE_ARG(aIsComplete);
00485   *aIsComplete = mRequest == nsnull;
00486   return NS_OK;
00487 }
00488 
00489 /* boolean abort (); */
00490 NS_IMETHODIMP nsHTTPSOAPTransportCompletion::Abort(PRBool * _retval)
00491 {
00492   NS_ENSURE_ARG(_retval);
00493   if (mRequest) {
00494     if (NS_SUCCEEDED(mRequest->Abort())) {
00495       *_retval = PR_TRUE;
00496       mRequest = nsnull;
00497       return NS_OK;
00498     }
00499   }
00500   *_retval = PR_FALSE;
00501   return NS_OK;
00502 }
00503 
00504 NS_IMETHODIMP
00505     nsHTTPSOAPTransportCompletion::HandleEvent(nsIDOMEvent * aEvent)
00506 {
00507   NS_ENSURE_ARG(aEvent);
00508 //  PRUint32 status;
00509   nsresult rv = NS_OK;
00510   if (mRequest) {                //  Avoid if it has been aborted.
00511 #if 0
00512     rv = mRequest->GetStatus(&status);
00513     if (NS_SUCCEEDED(rv) && (status < 200 || status >= 300))
00514       rv = NS_ERROR_FAILURE;
00515 #endif
00516     if (mResponse) { // && NS_SUCCEEDED(rv)) {
00517       nsCOMPtr<nsIDOMDocument> document;
00518       rv = mRequest->GetResponseXML(getter_AddRefs(document));
00519       if (NS_SUCCEEDED(rv) && document) {
00520         rv = mResponse->SetMessage(document);
00521         ChangePrincipal(document);
00522         DEBUG_DUMP_DOCUMENT("Asynchronous Response", document)
00523       } 
00524       else {
00525         mResponse = nsnull;
00526       }
00527     } else {
00528       mResponse = nsnull;
00529     }
00530     nsCOMPtr<nsISOAPCallCompletion> kungFuDeathGrip = this;
00531     mRequest = nsnull;                //  Break cycle of references by releasing the request.
00532     PRBool c;                        //  In other transports, this may signal to stop returning if multiple returns
00533     mListener->HandleResponse(mResponse, mCall, rv, PR_TRUE, &c);
00534   }
00535   return NS_OK;
00536 }
00537 
00538 /* void asyncCall (in nsISOAPCall aCall, in nsISOAPResponseListener aListener, in nsISOAPResponse aResponse); */
00539 NS_IMETHODIMP
00540 nsHTTPSOAPTransport::AsyncCall(nsISOAPCall * aCall,
00541                                nsISOAPResponseListener * aListener,
00542                                nsISOAPResponse * aResponse,
00543                                nsISOAPCallCompletion ** aCompletion)
00544 {
00545   NS_ENSURE_ARG(aCall);
00546   NS_ENSURE_ARG(aCompletion);
00547 
00548 
00549   nsCOMPtr<nsIDOMDocument> messageDocument;
00550   nsresult rv = aCall->GetMessage(getter_AddRefs(messageDocument));
00551   if (NS_FAILED(rv))
00552     return rv;
00553   if (!messageDocument)
00554     return SOAP_EXCEPTION(NS_ERROR_NOT_INITIALIZED,"SOAP_MESSAGE_DOCUMENT", "No message document is present.");
00555   DEBUG_DUMP_DOCUMENT("Asynchronous Request", messageDocument)
00556 
00557   nsCOMPtr<nsIXMLHttpRequest> request;
00558   rv = SetupRequest(aCall, PR_TRUE, getter_AddRefs(request));
00559   if (NS_FAILED(rv))
00560     return rv;
00561 
00562   nsCOMPtr<nsIDOMEventTarget> eventTarget = 
00563     do_QueryInterface(request, &rv);
00564   if (NS_FAILED(rv))
00565     return rv;
00566 
00567   nsCOMPtr<nsIWritableVariant> variant =
00568       do_CreateInstance(NS_VARIANT_CONTRACTID, &rv);
00569   if (NS_FAILED(rv))
00570     return rv;
00571 
00572   rv = variant->SetAsInterface(NS_GET_IID(nsIDOMDocument),
00573                                messageDocument);
00574   if (NS_FAILED(rv))
00575     return rv;
00576 
00577   nsCOMPtr<nsISOAPCallCompletion> completion;
00578 
00579   if (aListener) {
00580     completion =
00581         new nsHTTPSOAPTransportCompletion(aCall, aResponse, request,
00582                                           aListener);
00583     if (!completion)
00584       return NS_ERROR_OUT_OF_MEMORY;
00585 
00586     nsCOMPtr<nsIDOMEventListener> listener =
00587         do_QueryInterface(completion);
00588     rv = eventTarget->AddEventListener(NS_LITERAL_STRING("load"), listener,
00589                                        PR_FALSE);
00590     if (NS_FAILED(rv))
00591       return rv;
00592     rv = eventTarget->AddEventListener(NS_LITERAL_STRING("error"),
00593                                        listener, PR_FALSE);
00594     if (NS_FAILED(rv))
00595       return rv;
00596   }
00597   rv = request->Send(variant);
00598   if (NS_FAILED(rv))
00599     return rv;
00600 
00601   *aCompletion = completion;
00602   NS_IF_ADDREF(*aCompletion);
00603 
00604   return NS_OK;
00605 }
00606 
00607 /* void addListener (in nsISOAPTransportListener aListener, in boolean aCapture); */
00608 NS_IMETHODIMP
00609     nsHTTPSOAPTransport::AddListener(nsISOAPTransportListener * aListener,
00610                                      PRBool aCapture)
00611 {
00612   return NS_ERROR_NOT_IMPLEMENTED;
00613 }
00614 
00615 /* void removeListener (in nsISOAPTransportListener aListener, in boolean aCapture); */
00616 NS_IMETHODIMP
00617     nsHTTPSOAPTransport::RemoveListener(nsISOAPTransportListener *
00618                                         aListener, PRBool aCapture)
00619 {
00620   return NS_ERROR_NOT_IMPLEMENTED;
00621 }
00622 
00623 nsHTTPSSOAPTransport::nsHTTPSSOAPTransport()
00624 {
00625 }
00626 
00627 nsHTTPSSOAPTransport::~nsHTTPSSOAPTransport()
00628 {
00629 }
00630 
00631 NS_IMPL_ISUPPORTS1_CI(nsHTTPSSOAPTransport, nsISOAPTransport)