1
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2
/* ***** BEGIN LICENSE BLOCK *****
3
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
5
* The contents of this file are subject to the Mozilla Public License Version
6
* 1.1 (the "License"); you may not use this file except in compliance with
7
* the License. You may obtain a copy of the License at
8
* http://www.mozilla.org/MPL/
10
* Software distributed under the License is distributed on an "AS IS" basis,
11
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12
* for the specific language governing rights and limitations under the
15
* The Original Code is the web scripts access security code.
17
* The Initial Developer of the Original Code is
18
* Netscape Communications Corporation.
19
* Portions created by the Initial Developer are Copyright (C) 2002
20
* the Initial Developer. All Rights Reserved.
22
* Contributor(s): Harish Dhurvasula <harishd@netscape.com>
24
* Alternatively, the contents of this file may be used under the terms of
25
* either the GNU General Public License Version 2 or later (the "GPL"), or
26
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
27
* in which case the provisions of the GPL or the LGPL are applicable instead
28
* of those above. If you wish to allow use of your version of this file only
29
* under the terms of either the GPL or the LGPL, and not to allow others to
30
* use your version of this file under the terms of the MPL, indicate your
31
* decision by deleting the provisions above and replace them with the notice
32
* and other provisions required by the GPL or the LGPL. If you do not delete
33
* the provisions above, a recipient may use your version of this file under
34
* the terms of any one of the MPL, the GPL or the LGPL.
36
* ***** END LICENSE BLOCK ***** */
38
#include "nsWebScriptsAccess.h"
40
#include "nsAutoPtr.h"
41
#include "nsIDOMDocument.h"
42
#include "nsIDOMElement.h"
43
#include "nsIDOMNodeList.h"
44
#include "nsIDOMAttr.h"
45
#include "nsIDOMNamedNodeMap.h"
46
#include "nsIPrincipal.h"
48
#include "nsReadableUtils.h"
49
#include "nsIHttpChannel.h"
50
#include "nsNetUtil.h"
51
#include "nsIXPConnect.h"
54
#include "nsISOAPCall.h"
55
#include "nsISOAPEncoding.h"
56
#include "nsISOAPResponse.h"
57
#include "nsISOAPFault.h"
58
#include "nsISOAPParameter.h"
59
#include "nsISOAPBlock.h"
60
#include "nsIVariant.h"
61
#include "nsIPrefService.h"
62
#include "nsIPrefBranchInternal.h"
63
#include "nsIJSContextStack.h"
65
#define WSA_GRANT_ACCESS_TO_ALL (1 << 0)
66
#define WSA_FILE_NOT_FOUND (1 << 1)
67
#define WSA_FILE_DELEGATED (1 << 2)
68
#define SERVICE_LISTED_PUBLIC (1 << 3)
69
#define HAS_MASTER_SERVICE_DECISION (1 << 4)
71
static PRBool PR_CALLBACK
72
FreeEntries(nsHashKey *aKey, void *aData, void* aClosure)
74
AccessInfoEntry* entry = NS_REINTERPRET_CAST(AccessInfoEntry*, aData);
79
NS_IMPL_ISUPPORTS1(nsWebScriptsAccess,
80
nsIWebScriptsAccessService)
82
nsWebScriptsAccess::nsWebScriptsAccess()
83
: NS_LITERAL_STRING_INIT(kNamespace2002, "http://www.mozilla.org/2002/soap/security")
84
, NS_LITERAL_STRING_INIT(kWebScriptAccessTag, "webScriptAccess")
85
, NS_LITERAL_STRING_INIT(kDelegateTag, "delegate")
86
, NS_LITERAL_STRING_INIT(kAllowTag, "allow")
87
, NS_LITERAL_STRING_INIT(kTypeAttr, "type")
88
, NS_LITERAL_STRING_INIT(kFromAttr, "from")
89
, NS_LITERAL_STRING_INIT(kAny, "any")
90
, NS_LITERAL_STRING_INIT(kIsServicePublic, "isServicePublic")
94
nsWebScriptsAccess::~nsWebScriptsAccess()
96
mAccessInfoTable.Enumerate(FreeEntries, this);
100
nsWebScriptsAccess::CanAccess(nsIURI* aTransportURI,
101
const nsAString& aRequestType,
102
PRBool* aAccessGranted)
104
*aAccessGranted = PR_FALSE;
105
NS_ENSURE_ARG_POINTER(aTransportURI);
108
if (!mSecurityManager) {
109
mSecurityManager = do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID, &rv);
110
NS_ENSURE_SUCCESS(rv, rv);
114
mSecurityManager->IsCapabilityEnabled("UniversalBrowserRead",
116
if (NS_FAILED(rv) || *aAccessGranted)
119
mServiceURI = aTransportURI;
122
aTransportURI->GetPrePath(path);
125
AccessInfoEntry* entry = 0;
126
rv = GetAccessInfoEntry(path, &entry);
128
rv = mSecurityManager->CheckSameOrigin(0, aTransportURI);
129
if (NS_SUCCEEDED(rv)) {
130
// script security manager has granted access
131
*aAccessGranted = PR_TRUE;
135
// Script security manager has denied access and has set an
136
// exception. Clear the exception and fall back on the new
137
// security model's decision.
138
nsCOMPtr<nsIXPConnect> xpc(do_GetService(nsIXPConnect::GetCID()));
140
nsCOMPtr<nsIXPCNativeCallContext> cc;
141
xpc->GetCurrentNativeCallContext(getter_AddRefs(cc));
144
rv = cc->GetJSContext(&cx);
145
NS_ENSURE_SUCCESS(rv, rv);
147
JS_ClearPendingException(cx);
148
cc->SetExceptionWasThrown(PR_FALSE);
153
rv = CreateEntry(path, PR_FALSE, &entry);
154
NS_ENSURE_SUCCESS(rv, rv);
157
return CheckAccess(entry, aRequestType, aAccessGranted);
161
nsWebScriptsAccess::InvalidateCache(const char* aTransportURI)
164
nsCStringKey key(aTransportURI);
165
if (mAccessInfoTable.Exists(&key)) {
166
AccessInfoEntry* entry =
167
NS_REINTERPRET_CAST(AccessInfoEntry*, mAccessInfoTable.Remove(&key));
172
// If a URI is not specified then we clear the entire cache.
173
mAccessInfoTable.Enumerate(FreeEntries, this);
179
nsWebScriptsAccess::GetAccessInfoEntry(const char* aKey,
180
AccessInfoEntry** aEntry)
182
nsCStringKey key(aKey);
184
*aEntry = NS_REINTERPRET_CAST(AccessInfoEntry*, mAccessInfoTable.Get(&key));
185
if (*aEntry && ((*aEntry)->mFlags & WSA_FILE_DELEGATED)) {
187
nsCOMPtr<nsIURL> url(do_QueryInterface(mServiceURI, &rv));
188
NS_ENSURE_SUCCESS(rv, rv);
191
url->GetPrePath(path);
192
nsCAutoString directory;
193
url->GetDirectory(directory);
196
return GetAccessInfoEntry(path.get(), aEntry);
202
nsWebScriptsAccess::GetDocument(const nsACString& aDeclFilePath,
203
nsIDOMDocument** aDocument)
208
mRequest = do_CreateInstance(NS_XMLHTTPREQUEST_CONTRACTID, &rv);
209
NS_ENSURE_SUCCESS(rv, rv);
212
const nsAString& empty = EmptyString();
213
rv = mRequest->OpenRequest(NS_LITERAL_CSTRING("GET"), aDeclFilePath,
214
PR_FALSE, empty, empty);
215
NS_ENSURE_SUCCESS(rv, rv);
217
rv = mRequest->OverrideMimeType(NS_LITERAL_CSTRING("text/xml"));
218
NS_ENSURE_SUCCESS(rv, rv);
220
rv = mRequest->Send(0);
221
NS_ENSURE_SUCCESS(rv, rv);
223
nsCOMPtr<nsIChannel> channel;
224
mRequest->GetChannel(getter_AddRefs(channel));
225
nsCOMPtr<nsIHttpChannel> httpChannel(do_QueryInterface(channel, &rv));
226
NS_ENSURE_TRUE(httpChannel, rv);
229
httpChannel->GetRequestSucceeded(&succeeded);
232
rv = mRequest->GetResponseXML(aDocument);
233
NS_ENSURE_SUCCESS(rv, rv);
240
nsWebScriptsAccess::GetCodebaseURI(nsIURI** aCodebase)
244
if (!mSecurityManager) {
246
do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID, &rv);
247
NS_ENSURE_SUCCESS(rv, rv);
250
nsCOMPtr<nsIPrincipal> principal;
251
rv = mSecurityManager->GetSubjectPrincipal(getter_AddRefs(principal));
252
NS_ENSURE_SUCCESS(rv, rv);
254
return principal->GetURI(aCodebase);
258
nsWebScriptsAccess::CreateEntry(const char* aKey,
259
const PRBool aIsDelegated,
260
AccessInfoEntry** aEntry)
262
NS_ENSURE_ARG_POINTER(aEntry);
264
// create an entry by loading the declaration file (
265
// web-scripts-access.xml ) and extracting access information from
266
// it. Record the extracted info. for this session
267
nsCOMPtr<nsIDOMDocument> document;
269
GetDocument(nsDependentCString(aKey) +
270
NS_LITERAL_CSTRING("web-scripts-access.xml"),
271
getter_AddRefs(document));
272
NS_ENSURE_SUCCESS(rv, rv);
274
// Create an entry by extracting access information from the document.
275
rv = CreateEntry(document, aIsDelegated, aEntry);
276
NS_ENSURE_SUCCESS(rv, rv);
278
// If the document is invalid then an entry will not be created.
283
rv = CreateEntry(WSA_FILE_NOT_FOUND, aEntry);
284
NS_ENSURE_SUCCESS(rv, rv);
286
nsCStringKey key(aKey);
287
mAccessInfoTable.Put(&key, *aEntry);
289
NS_ASSERTION(*aEntry, "unexpected: access info entry is null!");
290
if (*aEntry && ((*aEntry)->mFlags & WSA_FILE_DELEGATED))
291
rv = CreateDelegatedEntry(aEntry);
296
nsWebScriptsAccess::CreateEntry(nsIDOMDocument* aDocument,
297
const PRBool aIsDelegated,
298
AccessInfoEntry** aEntry)
300
NS_ENSURE_ARG_POINTER(aDocument);
301
NS_ENSURE_ARG_POINTER(aEntry);
305
nsresult rv = ValidateDocument(aDocument, &valid);
306
NS_ENSURE_SUCCESS(rv, rv);
309
return NS_OK; // XXX should I return an error instead ?
313
nsCOMPtr<nsIDOMNodeList> delegateList;
314
rv = aDocument->GetElementsByTagNameNS(kNamespace2002, kDelegateTag,
315
getter_AddRefs(delegateList));
316
NS_ENSURE_TRUE(delegateList, rv);
317
nsCOMPtr<nsIDOMNode> node;
318
delegateList->Item(0, getter_AddRefs(node));
320
return CreateEntry(WSA_FILE_DELEGATED, aEntry);
323
nsCOMPtr<nsIDOMNodeList> allowList;
324
rv = aDocument->GetElementsByTagNameNS(kNamespace2002, kAllowTag,
325
getter_AddRefs(allowList));
326
NS_ENSURE_TRUE(allowList, rv);
329
allowList->GetLength(&count);
331
rv = CreateEntry(allowList, aEntry);
334
// Since there are no ALLOW elements present grant access to all.
335
rv = CreateEntry(WSA_GRANT_ACCESS_TO_ALL, aEntry);
342
nsWebScriptsAccess::CreateEntry(const PRInt32 aFlags,
343
AccessInfoEntry** aEntry)
345
*aEntry = new AccessInfoEntry(aFlags);
346
NS_ENSURE_TRUE(*aEntry, NS_ERROR_OUT_OF_MEMORY);
352
nsWebScriptsAccess::CreateEntry(nsIDOMNodeList* aAllowList,
353
AccessInfoEntry** aEntry)
355
NS_ENSURE_ARG_POINTER(aAllowList);
356
NS_ENSURE_ARG_POINTER(aEntry);
359
nsAutoPtr<AccessInfoEntry> entry(new AccessInfoEntry());
360
NS_ENSURE_TRUE(entry, NS_ERROR_OUT_OF_MEMORY);
363
aAllowList->GetLength(&count);
366
nsCOMPtr<nsIDOMNode> node;
367
nsAutoString type, from;
368
for (index = 0; index < count; index++) {
369
aAllowList->Item(index, getter_AddRefs(node));
370
NS_ENSURE_TRUE(node, NS_ERROR_UNEXPECTED);
372
nsCOMPtr<nsIDOMElement> element(do_QueryInterface(node));
373
element->GetAttribute(kTypeAttr, type);
374
element->GetAttribute(kFromAttr, from);
376
PRBool found_type = !type.IsEmpty();
377
PRBool found_from = !from.IsEmpty();
379
if (!found_type && !found_from) {
380
// Minor optimization - If the "type" and "from"
381
// attributes aren't present then no need to check
382
// for attributes in other "allow" elements because
383
// access will be granted to all regardless.
384
entry->mFlags |= WSA_GRANT_ACCESS_TO_ALL;
388
nsAutoPtr<AccessInfo> access_info(new AccessInfo());
389
NS_ENSURE_TRUE(access_info, NS_ERROR_OUT_OF_MEMORY);
392
access_info->mType = ToNewUnicode(type);
393
NS_ENSURE_TRUE(access_info->mType, NS_ERROR_OUT_OF_MEMORY);
397
access_info->mFrom = ToNewUnicode(from);
398
NS_ENSURE_TRUE(access_info->mFrom, NS_ERROR_OUT_OF_MEMORY);
401
entry->mInfoArray.AppendElement(access_info.forget());
407
*aEntry = entry.forget();
413
nsWebScriptsAccess::CreateDelegatedEntry(AccessInfoEntry** aEntry)
415
NS_ENSURE_ARG_POINTER(aEntry);
419
nsCOMPtr<nsIURL> url(do_QueryInterface(mServiceURI, &rv));
420
NS_ENSURE_SUCCESS(rv, rv);
423
url->GetPrePath(path);
424
nsCAutoString directory;
425
url->GetDirectory(directory);
428
return CreateEntry(path.get(), PR_TRUE, aEntry);
432
nsWebScriptsAccess::CheckAccess(AccessInfoEntry* aEntry,
433
const nsAString& aRequestType,
434
PRBool* aAccessGranted)
437
static PRBool verified = PR_FALSE;
440
nsWSAUtils::VerifyIsEqual();
444
*aAccessGranted = PR_FALSE;
445
NS_ENSURE_ARG_POINTER(aEntry);
448
if (aEntry->mFlags & WSA_FILE_NOT_FOUND) {
449
if (aEntry->mFlags & HAS_MASTER_SERVICE_DECISION) {
450
if (aEntry->mFlags & SERVICE_LISTED_PUBLIC)
451
*aAccessGranted = PR_TRUE;
455
rv = nsWSAUtils::GetOfficialHostName(mServiceURI, fqdn);
456
if (NS_FAILED(rv) || fqdn.IsEmpty())
459
PRBool isPublic = PR_FALSE;
460
rv = IsPublicService(fqdn.get(), &isPublic);
461
if (NS_SUCCEEDED(rv)) {
463
aEntry->mFlags |= SERVICE_LISTED_PUBLIC;
464
*aAccessGranted = PR_TRUE;
466
aEntry->mFlags |= HAS_MASTER_SERVICE_DECISION;
471
if (aEntry->mFlags & WSA_GRANT_ACCESS_TO_ALL) {
472
*aAccessGranted = PR_TRUE;
476
nsCOMPtr<nsIURI> codebase_uri;
477
rv = GetCodebaseURI(getter_AddRefs(codebase_uri));
478
NS_ENSURE_SUCCESS(rv, rv);
481
codebase_uri->GetSpec(tmp);
482
const nsAString& codebase = NS_ConvertUTF8toUCS2(tmp);
484
PRUint32 count = aEntry->mInfoArray.Count();
486
for (index = 0; index < count; index++) {
487
AccessInfo* access_info =
488
NS_REINTERPRET_CAST(AccessInfo*, aEntry->mInfoArray.ElementAt(index));
489
NS_ASSERTION(access_info, "Entry is missing attribute information");
491
if (!access_info->mType || kAny.Equals(access_info->mType) ||
492
aRequestType.Equals(access_info->mType)) {
493
if (!access_info->mFrom) {
494
// If "from" is not specified, then all scripts will be allowed
495
*aAccessGranted = PR_TRUE;
499
if (nsWSAUtils::IsEqual(nsDependentString(access_info->mFrom),
501
*aAccessGranted = PR_TRUE;
512
* Validation is based on the following syntax:
514
* <!ELEMENT webScriptAccess (delegate?|allow*)>
515
* <!ELEMENT delegate EMPTY>
516
* <!ELEMENT allow EMPTY>
517
* <!ATTLIST allow type|from CDATA #IMPLIED>.
521
nsWebScriptsAccess::ValidateDocument(nsIDOMDocument* aDocument,
524
NS_ENSURE_ARG_POINTER(aDocument);
526
*aIsValid = PR_FALSE;
527
nsCOMPtr<nsIDOMElement> rootElement;
528
aDocument->GetDocumentElement(getter_AddRefs(rootElement));
532
nsresult rv = rootElement->GetNamespaceURI(ns);
535
rootElement->GetLocalName(name);
539
if (!ns.Equals(kNamespace2002)) {
540
const PRUnichar *inputs[1] = { ns.get() };
541
return nsWSAUtils::ReportError(
542
NS_LITERAL_STRING("UnsupportedNamespace").get(),
545
if (!name.Equals(kWebScriptAccessTag)) {
546
const PRUnichar *inputs[1] = { name.get() };
547
return nsWSAUtils::ReportError(
548
NS_LITERAL_STRING("UnknownRootElement").get(),
552
nsCOMPtr<nsIDOMNode> rootNode(do_QueryInterface(rootElement));
553
NS_ENSURE_TRUE(rootNode, NS_ERROR_UNEXPECTED);
555
nsCOMPtr<nsIDOMNodeList> children;
556
rootNode->GetChildNodes(getter_AddRefs(children));
557
NS_ENSURE_TRUE(children, NS_ERROR_UNEXPECTED);
560
children->GetLength(&length);
562
PRBool hadDelegate = PR_FALSE;
563
nsCOMPtr<nsIDOMNode> child, attr;
564
nsCOMPtr<nsIDOMNamedNodeMap> attrs;
566
for (i = 0; i < length; i++) {
567
children->Item(i, getter_AddRefs(child));
568
NS_ENSURE_TRUE(child, NS_ERROR_UNEXPECTED);
571
child->GetNodeType(&type);
573
if (nsIDOMNode::ELEMENT_NODE == type) {
574
rv = child->GetNamespaceURI(ns);
577
rv = child->GetLocalName(name);
581
if (!ns.Equals(kNamespace2002))
582
continue; // ignore elements with different ns.
584
PRBool hasChildNodes = PR_FALSE;
585
if (name.Equals(kDelegateTag)) {
586
// There can me no more than one delegate element.
588
const PRUnichar *inputs[1] = { name.get() };
589
return nsWSAUtils::ReportError(
590
NS_LITERAL_STRING("TooManyElements").get(),
593
// Make sure that the delegate element is EMPTY.
594
child->HasChildNodes(&hasChildNodes);
596
const PRUnichar *inputs[1] = { name.get() };
597
return nsWSAUtils::ReportError(
598
NS_LITERAL_STRING("ElementNotEmpty").get(),
601
hadDelegate = PR_TRUE;
603
else if (name.Equals(kAllowTag)) {
604
// Make sure that the allow element is EMPTY.
605
child->HasChildNodes(&hasChildNodes);
607
const PRUnichar *inputs[1] = { name.get() };
608
return nsWSAUtils::ReportError(
609
NS_LITERAL_STRING("ElementNotEmpty").get(),
612
rv = child->GetAttributes(getter_AddRefs(attrs));
617
attrs->GetLength(&count);
618
for (i = 0; i < count; i++) {
619
attrs->Item(i, getter_AddRefs(attr));
621
rv = attr->GetLocalName(name);
624
if (!name.Equals(kTypeAttr) && !name.Equals(kFromAttr)) {
625
const PRUnichar *inputs[1] = { name.get() };
626
return nsWSAUtils::ReportError(
627
NS_LITERAL_STRING("UnknownAttribute").get(),
634
const PRUnichar *inputs[1] = { name.get() };
635
return nsWSAUtils::ReportError(
636
NS_LITERAL_STRING("UnknownElement").get(),
647
IsCharInSet(const char* aSet,
648
const PRUnichar aChar)
651
while ((ch = *aSet)) {
652
if (aChar == PRUnichar(ch)) {
661
nsWebScriptsAccess::IsPublicService(const char* aHost, PRBool* aReturn)
665
// Cache the master services included in the prefs.
666
if (mMasterServices.Count() == 0) {
667
nsCOMPtr<nsIPrefBranch> prefBranch =
668
do_GetService(NS_PREFSERVICE_CONTRACTID);
673
nsXPIDLCString value;
674
rv = prefBranch->GetCharPref("xml.webservice.security.masterservices",
675
getter_Copies(value));
677
if (NS_FAILED(rv) || value.IsEmpty())
680
nsACString::const_iterator begin, end, curr;
681
nsACString::const_iterator uri_begin, uri_end;
682
value.BeginReading(begin);
683
value.EndReading(end);
685
// Parse the comma separated pref. value
686
static const char* kWhitespace = " \n\r\t\b";
687
while (begin != end) {
689
// strip leading whitespaces
690
while (IsCharInSet(kWhitespace, *curr) && ++curr != end);
692
// consume until the delimiter ( comma ).
693
while (curr != end && *curr != ',')
696
// strip trailing whitespaces
697
while (uri_end != uri_begin) {
698
if (!IsCharInSet(kWhitespace, *(--uri_end))) {
699
++uri_end; // include the last non whitespace char.
703
const nsAFlatString& transportURI =
704
NS_ConvertUTF8toUCS2(Substring(uri_begin, uri_end));
705
if (!transportURI.IsEmpty())
706
mMasterServices.AppendString(transportURI);
707
begin = (*curr == ',' && curr != end) ? ++curr : curr;
711
// Do nothing if the pref value turns out to be
712
// strings with nothing but whitespaces.
713
if (mMasterServices.Count() == 0)
716
// Allocate param block.
717
nsISOAPParameter** bodyBlocks =
718
NS_STATIC_CAST(nsISOAPParameter**,
719
nsMemory::Alloc(1 * sizeof(nsISOAPParameter*)));
721
return NS_ERROR_OUT_OF_MEMORY;
724
CallCreateInstance(NS_SOAPPARAMETER_CONTRACTID, &bodyBlocks[0]);
727
NS_FREE_XPCOM_ISUPPORTS_POINTER_ARRAY(0, bodyBlocks);
731
nsCOMPtr<nsISOAPBlock> block = do_QueryInterface(bodyBlocks[0], &rv);
736
block->SetName(NS_LITERAL_STRING("fqdn"));
738
nsCOMPtr <nsIWritableVariant> variant =
739
do_CreateInstance(NS_VARIANT_CONTRACTID, &rv);
744
variant->SetAsString(aHost);
746
block->SetValue(variant);
748
// Create the call instance
749
nsCOMPtr<nsISOAPCall> call =
750
do_CreateInstance(NS_SOAPCALL_CONTRACTID, &rv);
755
nsCOMPtr<nsISOAPEncoding> encoding =
756
do_CreateInstance(NS_SOAPENCODING_CONTRACTID, &rv);
761
call->SetEncoding(encoding);
763
// Since the SOAP request to the central server will be made
764
// from the native code we can safely override cross-domain
765
// checks by pushing in a null jscontext on the context stack.
766
nsCOMPtr<nsIJSContextStack> stack =
767
do_GetService("@mozilla.org/js/xpc/ContextStack;1");
771
nsCOMPtr<nsISOAPResponse> response;
772
PRInt32 i, count = mMasterServices.Count();
773
for (i = 0; i < count && !response; i++) {
775
call->SetTransportURI(*mMasterServices.StringAt(i));
780
rv = call->Encode(nsISOAPMessage::VERSION_1_1,
782
kNamespace2002, // The target URI
783
0, 0, 1, bodyBlocks);
787
call->Invoke(getter_AddRefs(response)); // XXX - How to handle time out and 404?
793
NS_ASSERTION(!cx, "context should be null");
799
nsCOMPtr<nsISOAPFault> fault;
800
response->GetFault(getter_AddRefs(fault));
803
nsAutoString faultNamespaceURI, faultCode, faultString;
804
fault->GetFaultNamespaceURI(faultNamespaceURI);
805
fault->GetFaultCode(faultCode);
806
fault->GetFaultString(faultString);
807
const PRUnichar *inputs[5] =
809
kNamespace2002.get(),
810
kIsServicePublic.get(),
811
faultNamespaceURI.get(),
815
return nsWSAUtils::ReportError(
816
NS_LITERAL_STRING("SOAPFault").get(),
821
rv = response->GetParameters(PR_FALSE, &bodyCount, &bodyBlocks);
822
NS_ASSERTION(bodyBlocks, "insufficient information");
824
if (!bodyBlocks || NS_FAILED(rv))
827
NS_ASSERTION(bodyCount == 1, "body seems to contain unnecessary information.");
828
block = do_QueryInterface(bodyBlocks[0], &rv);
833
nsCOMPtr<nsIVariant> value;
834
rv = block->GetValue(getter_AddRefs(value));
836
if (NS_FAILED(rv) || !value)
839
rv = value->GetAsBool(aReturn);