From 1a673fff790799642df5468275401a4176a30939 Mon Sep 17 00:00:00 2001 From: "allan%beaufour.dk" Date: Thu, 13 Oct 2005 09:46:17 +0000 Subject: [PATCH] [XForms] Support SOAPAction header on submission (set xforms.enableExperimentalFeatures to enable). Bug 309442, r=aaronr, smaug, doronr --- .../xforms/nsXFormsSubmissionElement.cpp | 78 +++++++++++++++++-- extensions/xforms/nsXFormsSubmissionElement.h | 2 + extensions/xforms/nsXFormsUtils.h | 1 + .../resources/locale/en-US/xforms.properties | 3 + 4 files changed, 79 insertions(+), 5 deletions(-) diff --git a/extensions/xforms/nsXFormsSubmissionElement.cpp b/extensions/xforms/nsXFormsSubmissionElement.cpp index 7f367809c3c4..62ae3030f45d 100644 --- a/extensions/xforms/nsXFormsSubmissionElement.cpp +++ b/extensions/xforms/nsXFormsSubmissionElement.cpp @@ -93,6 +93,7 @@ #include "nsIPermissionManager.h" #include "nsIPrefBranch.h" #include "nsIPrefService.h" +#include "nsIMIMEHeaderParam.h" // namespace literals #define NAMESPACE_XML_SCHEMA \ @@ -603,6 +604,7 @@ nsXFormsSubmissionElement::Submit() LOG(("+++ nsXFormsSubmissionElement::Submit\n")); nsresult rv; + mIsSOAPRequest = PR_FALSE; // 1. ensure that we are not currently processing a xforms-submit (see E37) NS_ENSURE_STATE(!mSubmissionActive); @@ -773,13 +775,57 @@ nsXFormsSubmissionElement::SerializeDataXML(nsIDOMNode *data, nsCString &contentType, SubmissionAttachmentArray *attachments) { + nsresult rv; nsAutoString mediaType; mElement->GetAttribute(NS_LITERAL_STRING("mediatype"), mediaType); - if (mediaType.IsEmpty()) - contentType.AssignLiteral("application/xml"); - else - CopyUTF16toUTF8(mediaType, contentType); + // Check for preference, disabling SOAP requests + PRBool enableExperimental = PR_FALSE; + nsCOMPtr pref = do_GetService(NS_PREFSERVICE_CONTRACTID, &rv); + if (NS_SUCCEEDED(rv) && pref) { + PRBool val; + if (NS_SUCCEEDED(pref->GetBoolPref("xforms.enableExperimentalFeatures", + &val))) + enableExperimental = val; + } + + // Check for SOAP Envelope and handle SOAP + if (enableExperimental) { + nsAutoString nodeName, nodeNS; + data->GetLocalName(nodeName); + data->GetNamespaceURI(nodeNS); + if (nodeName.Equals(NS_LITERAL_STRING("Envelope")) && + nodeNS.Equals(NS_LITERAL_STRING(NS_NAMESPACE_SOAP_ENVELOPE))) { + mIsSOAPRequest = PR_TRUE; + nsXFormsUtils::ReportError(NS_LITERAL_STRING("warnSOAP"), mElement, + nsIScriptError::warningFlag); + contentType.AssignLiteral("text/xml"); + + if (!mediaType.IsEmpty()) { + // copy charset from mediatype + nsAutoString charset; + nsCOMPtr mimeHdrParser = + do_GetService("@mozilla.org/network/mime-hdrparam;1"); + NS_ENSURE_STATE(mimeHdrParser); + rv = mimeHdrParser->GetParameter(NS_ConvertUTF16toUTF8(mediaType), + "charset", EmptyCString(), PR_FALSE, + nsnull, charset); + if (NS_SUCCEEDED(rv) && !charset.IsEmpty()) { + contentType.AppendLiteral("; charset="); + contentType.Append(NS_ConvertUTF16toUTF8(charset)); + } + } + } + } + + // Handle non-SOAP requests + if (!mIsSOAPRequest) { + if (mediaType.IsEmpty()) + contentType.AssignLiteral("application/xml"); + else + CopyUTF16toUTF8(mediaType, contentType); + } + nsAutoString encoding; mElement->GetAttribute(NS_LITERAL_STRING("encoding"), encoding); if (encoding.IsEmpty()) @@ -800,7 +846,6 @@ nsXFormsSubmissionElement::SerializeDataXML(nsIDOMNode *data, nsCOMPtr doc, newDoc; data->GetOwnerDocument(getter_AddRefs(doc)); - nsresult rv; // XXX: We can't simply pass in data if !doc, since it crashes if (!doc) { // owner doc is null when the data node is the document (e.g., ref="/") @@ -1840,6 +1885,29 @@ nsXFormsSubmissionElement::SendData(const nsCString &uriSpec, rv = httpChannel->SetRequestMethod(NS_LITERAL_CSTRING("POST")); NS_ENSURE_SUCCESS(rv, rv); + + if (mIsSOAPRequest) { + nsCOMPtr mimeHdrParser = + do_GetService("@mozilla.org/network/mime-hdrparam;1"); + NS_ENSURE_STATE(mimeHdrParser); + + nsAutoString mediatype, action; + mElement->GetAttribute(NS_LITERAL_STRING("mediatype"), + mediatype); + if (!mediatype.IsEmpty()) { + + rv = mimeHdrParser->GetParameter(NS_ConvertUTF16toUTF8(mediatype), + "action", EmptyCString(), PR_FALSE, + nsnull, action); + } + if (action.IsEmpty()) { + action.AssignLiteral(" "); + } + rv = httpChannel->SetRequestHeader(NS_LITERAL_CSTRING("SOAPAction"), + NS_ConvertUTF16toUTF8(action), + PR_FALSE); + NS_ENSURE_SUCCESS(rv, rv); + } } // set loadGroup and notificationCallbacks diff --git a/extensions/xforms/nsXFormsSubmissionElement.h b/extensions/xforms/nsXFormsSubmissionElement.h index a1feb37144e0..28c1f7a3caed 100644 --- a/extensions/xforms/nsXFormsSubmissionElement.h +++ b/extensions/xforms/nsXFormsSubmissionElement.h @@ -83,6 +83,7 @@ public: : mElement(nsnull) , mSubmissionActive(PR_FALSE) , mIsReplaceInstance(PR_FALSE) + , mIsSOAPRequest(PR_FALSE) , mFormat(0) {} @@ -118,6 +119,7 @@ private: nsIDOMElement *mElement; PRPackedBool mSubmissionActive; PRPackedBool mIsReplaceInstance; // Valid when mSubmissionActive == PR_TRUE + PRPackedBool mIsSOAPRequest; PRUint32 mFormat; // Valid when mSubmissionActive == PR_TRUE nsCOMPtr mActivator; diff --git a/extensions/xforms/nsXFormsUtils.h b/extensions/xforms/nsXFormsUtils.h index 1e4e17aff132..a8aec52c2229 100644 --- a/extensions/xforms/nsXFormsUtils.h +++ b/extensions/xforms/nsXFormsUtils.h @@ -61,6 +61,7 @@ class nsIDOMEvent; #define NS_NAMESPACE_XML_SCHEMA "http://www.w3.org/2001/XMLSchema" #define NS_NAMESPACE_XML_SCHEMA_INSTANCE "http://www.w3.org/2001/XMLSchema-instance" #define NS_NAMESPACE_MOZ_XFORMS_TYPE "http://www.mozilla.org/projects/xforms/2005/type" +#define NS_NAMESPACE_SOAP_ENVELOPE "http://schemas.xmlsoap.org/soap/envelope/" #define NS_NAMESPACE_MOZ_XFORMS_LAZY "http://www.mozilla.org/projects/xforms/2005/lazy" /** diff --git a/extensions/xforms/resources/locale/en-US/xforms.properties b/extensions/xforms/resources/locale/en-US/xforms.properties index 4a7dadd7e9b0..02df06fd78e4 100644 --- a/extensions/xforms/resources/locale/en-US/xforms.properties +++ b/extensions/xforms/resources/locale/en-US/xforms.properties @@ -59,6 +59,9 @@ invalidSeparator = XForms Error (20): Submission separator may only be eithe instanceBindError = XForms Error (21): Submission failed trying to replace instance document '%S'. Instance document doesn't exist in same model as submission element. instanceInstanceLoad = XForms Error (22): Instance document not allowed to load external instance: %S +# Warning Messages: +warnSOAP = XForms Warning (1): You are using the SOAP post feature, which is an experimental feature! Beware that the functionality might change, and forms may stop working at any time. + # XForms Permission Messages: xformsXDPermissionDialogTitle = Allowed Sites - XForms Cross Domain Access xformsXDPermissionDialogIntro = You can specify which web sites containing XForms may submit data to other domains. Type the exact address of the site you want to allow and then press Allow.