зеркало из https://github.com/mozilla/pjs.git
Checking in first stab at SOAP API documentation.
This file is not presently built, and SOAP is not part of default build.
This commit is contained in:
Родитель
9e211aefda
Коммит
08cad986fe
|
@ -0,0 +1,550 @@
|
|||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="content-type" content="text/html; charset=ISO-8859-1">
|
||||
<title>Soap Scripts in Mozilla</title>
|
||||
</head>
|
||||
<body>
|
||||
<div align="Center">
|
||||
<h1>SOAP Scripts in Mozilla</h1>
|
||||
<font color="#999999">February 16, 2002</font><br>
|
||||
<h3><font color="#999999">Ray Whitmer</font></h3>
|
||||
<h2><font color="#666666">Abstract</font></h2>
|
||||
<div align="Left"><font color="#000000">Microsoft and others have advocated
|
||||
SOAP as a way to encode and exchange public data structures between agents
|
||||
on the web. The browser client is the most universal web agent in existence,
|
||||
and Javascript is the standard, interoperable way of scripting browsers.
|
||||
Scriptable SOAP in browsers gives clients and servers more to say to each
|
||||
other through existing http-xml services, providing scripts with persistence,
|
||||
database, and access to other web services not tied to the request and response
|
||||
cycles of the HTML-based user interface. Web data structures, exchanged
|
||||
in a platform-neutral way, should become as fundamental to web agents as
|
||||
web content is today. The key to this is a tight binding to the natural
|
||||
data of Javascript so that the script can simply use the data instead of
|
||||
tediously encoding and extracting the data from the XML.</font><br>
|
||||
<h2>SOAP Services</h2>
|
||||
There are a number of sources for services available on the web being set
|
||||
up, such as XMethods. Apache supports modules for SOAP that this author has
|
||||
used to author services for purposes of testing and entertainment.
|
||||
Once it is set up, it is as simple as writing a function in Javascript, Java,
|
||||
or any other of a number of supported languages and then writing a simple
|
||||
service description in XML or submitting a form to deploy the service.
|
||||
There are toolkits available from Microsoft and other webserver providers
|
||||
for authoring such services as well.<br>
|
||||
<h2>SOAP Blocks</h2>
|
||||
<h3>Parameters<br>
|
||||
</h3>
|
||||
SOAP-based services exchange message envelopes which contain blocks of XML
|
||||
data roughly corresponding to the parameters of a service call. When
|
||||
an rpc-style message is exchanged, blocks representing the regular parameter
|
||||
blocks are placed inside an element which identifies the object and method
|
||||
being invoked, which is placed inside the body. In a non-RPC message,
|
||||
the blocks are placed directly inside the body instead of under the method
|
||||
element. <br>
|
||||
<h3>Header Blocks<br>
|
||||
</h3>
|
||||
Blocks which are optional or are independently added or processed are placed
|
||||
inside the header with an assigned role and specially marked if the recipient
|
||||
is required to understand them.<br>
|
||||
<h3>Encodings<br>
|
||||
</h3>
|
||||
Interpretation of each block depends upon the encoding that was used, which
|
||||
is clearly specified in the message. If the standard SOAP encoding
|
||||
is used, then XML Schema types used to interpret the data within each block.<br>
|
||||
<h2>Using the Low-Level SOAP API</h2>
|
||||
To use the low-level API, the user creates a SOAPCall object, encodes the
|
||||
function call with a list of headers and regular parameters, and invokes the
|
||||
call, which returns a response which contains the results of the service call
|
||||
including a fault generated by the service which processed the message, output
|
||||
parameters, and/or header blocks. If the call is invoked asynchronously,
|
||||
then a function is given which receives the response when it arrives from
|
||||
the remote service.<br>
|
||||
<br>
|
||||
Besides Javascript, the below-described operations should also generally
|
||||
work for other xpconnect-supported languages in Mozilla such as C++/XPCOM
|
||||
and Python, because language-independent cross-platform interfaces were used.<br>
|
||||
<br>
|
||||
Object names or descriptions contained in angle brackets represent any object
|
||||
of the named or described type. Quoted angle brackets indicate a suitable
|
||||
string of the named or described value type.<br>
|
||||
<h3>Basic Operations<br>
|
||||
</h3>
|
||||
For most simple use cases, basic operations is all the user needs to do.<br>
|
||||
<br>
|
||||
<table cellpadding="2" cellspacing="2" border="1" width="100%">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td valign="Top">Basic Operation<br>
|
||||
</td>
|
||||
<td valign="Top">Ways to Access<br>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="Top">Set a Javascript value or object as the value of a
|
||||
message block<br>
|
||||
</td>
|
||||
<td valign="Top"><variable> = new SOAPParameter(<value>)<br>
|
||||
// or<br>
|
||||
<variable> = new SOAPHeader(<value>)<br>
|
||||
// or<br>
|
||||
<SOAPParameter>.value = <value><br>
|
||||
or<br>
|
||||
<SOAPHeaderBlock>.value = <value><br>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="Top">Get or set header blocks or parameters in a Javascript
|
||||
array<br>
|
||||
</td>
|
||||
<td valign="Top"><Array>[]<br>
|
||||
// or<br>
|
||||
new Array(<block>[,...]);<br>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="Top">Associate the arrays of header blocks and parameters
|
||||
with a message<br>
|
||||
</td>
|
||||
<td valign="Top"><SOAPCall>.encode(<0 or 1 for 1.1 or 1.2>,
|
||||
"<method>", "<object namespace>", <header count>, <headers>,
|
||||
<parameter count>, <parameters>)<br>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="Top">Invoke call (send call message and receive response
|
||||
message)<br>
|
||||
</td>
|
||||
<td valign="Top"><SOAPCall>.invoke()<br>
|
||||
// or<br>
|
||||
<SOAPCall>.asyncInvoke(<SOAPResponseListener>)<br>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="Top">Get the response's fault, if any<br>
|
||||
</td>
|
||||
<td valign="Top"><SOAPResponse>.fault<br>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="Top">Get the arrays of blocks from the response<br>
|
||||
</td>
|
||||
<td valign="Top"><variable> = <SOAPResponse>.getParameters(<true
|
||||
if not rpc-style>, {})<br>
|
||||
// or<br>
|
||||
<variable> = <SOAPResponse>.getHeaderBlocks({})<br>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="Top">Get a Javascript value or object from a response message
|
||||
block<br>
|
||||
</td>
|
||||
<td valign="Top"><variable> = <SOAPParameter>.value<br>
|
||||
// or<br>
|
||||
<variable> = <SOAPHeaderBlock>.value<br>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<h3>Sources of Objects for Basic Operations</h3>
|
||||
Source expressions can generally be placed on the right-side of an assignment
|
||||
(equals) operator to get an object of the listed type.<br>
|
||||
<br>
|
||||
<table cellpadding="2" cellspacing="2" border="1" width="100%">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td valign="Top">Basic Object Types<br>
|
||||
</td>
|
||||
<td valign="Top">Objects of Type Found Here<br>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="Top">SOAPParameter<br>
|
||||
</td>
|
||||
<td valign="Top">new SOAPParameter()<br>
|
||||
// or<br>
|
||||
<SOAPResponse>.getParameters(<true if not rpc-style>, {})<br>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="Top">SOAPHeaderBlock<br>
|
||||
</td>
|
||||
<td valign="Top">new SOAPHeaderBlock()<br>
|
||||
// or<br>
|
||||
SOAPResponse.getHeaderBlocks({})<br>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="Top">SOAPCall<br>
|
||||
</td>
|
||||
<td valign="Top">new SOAPCall()<br>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="Top">SOAPResponse<br>
|
||||
</td>
|
||||
<td valign="Top"><SOAPCall>.invoke()<br>
|
||||
// or<br>
|
||||
<SOAPCall>.asyncInvoke(<SOAPResponseListener>) // SOAPResponse
|
||||
delivered to listener<br>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="Top">SOAPResponseListener<br>
|
||||
</td>
|
||||
<td valign="Top"><Function accepting (<SOAPResponse>, <SOAPCall>,
|
||||
<status>)><br>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="Top">SOAPFault<br>
|
||||
</td>
|
||||
<td valign="Top"><SOAPResponse>.fault<br>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<br>
|
||||
<h3>Expert Operations -- To be Skipped by the Bleary-Eyed<br>
|
||||
</h3>
|
||||
When the default encoding, decoding, and handling is not adequate, the user
|
||||
has access to a variety of additional JS-accessible mechanisms to control
|
||||
the encoding and decoding of messages.<br>
|
||||
<br>
|
||||
<table cellpadding="2" cellspacing="2" border="1" width="100%">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td valign="Top">Operation<br>
|
||||
</td>
|
||||
<td valign="Top">Ways to Access<br>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="Top">Set or get the name and namespaceURI of a message
|
||||
block<br>
|
||||
</td>
|
||||
<td valign="Top"><variable> = new SOAPParameter(<value>,
|
||||
"<name>", "<namespaceURI>")<br>
|
||||
// or<br>
|
||||
<SOAPParameter>.name<br>
|
||||
// or<br>
|
||||
<SOAPParameter>.namespaceURI<br>
|
||||
// or<br>
|
||||
<variable> = new SOAPHeaderBlock(<value>, "<name>", "<namespaceURI>")<br>
|
||||
// or<br>
|
||||
<SOAPHeaderBlock>.name<br>
|
||||
// or<br>
|
||||
<SOAPHeaderBlock>.namespaceURI<br>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="Top">Mark / check role URI of header block<br>
|
||||
</td>
|
||||
<td valign="Top"><SOAPHeaderBlock>.actorURI<br>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="Top">Mark / check boolean value whether header must be
|
||||
understood by recipient or the message should be rejected<br>
|
||||
</td>
|
||||
<td valign="Top"><SOAPHeaderBlock>.mustUnderstand<br>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="Top">Check the actual SOAP version of an encoded message.<br>
|
||||
</td>
|
||||
<td valign="Top"><SOAPCall>.version<br>
|
||||
// or<br>
|
||||
<SOAPResponse>.version<br>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="Top">Abort an in-progress asynchronous call<br>
|
||||
</td>
|
||||
<td valign="Top"><SOAPCallCompletion>.abort()<br>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="Top">Map or unmap alias schema target URIs to be used --
|
||||
as SOAP 1.1 types are aliased 1.2 types<br>
|
||||
</td>
|
||||
<td valign="Top"><SOAPEncoding>.mapSchemaURI("<external URI>",
|
||||
"<internal URI>", <true to alias output>)<br>
|
||||
// or<br>
|
||||
<SOAPEncoding>.unmapSchemaURI("<external URI>")<br>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="Top">Associate a specific XML schema type (SchemaType)
|
||||
with the block to govern encoding or decoding<br>
|
||||
</td>
|
||||
<td valign="Top"><variable> = <SchemaCollection>.getType("<name>",
|
||||
"<namespaceURI>")<br>
|
||||
// and then<br>
|
||||
<variable2> = new SOAPParameter(<value>, "<name>", "<namespaceURI>",
|
||||
<SchemaType>)<br>
|
||||
// or<br>
|
||||
<SOAPParameter>.schemaType = <variable><br>
|
||||
// or<br>
|
||||
<variable2> = new SOAPHeaderBlock(<value>, "<name>", "<namespaceURI>",
|
||||
<SchemaType>)<br>
|
||||
// or<br>
|
||||
<SOAPHeaderBlock>.schemaType = <variable><br>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="Top">Associate a specific encoding with the call to govern
|
||||
encoding or decoding<br>
|
||||
</td>
|
||||
<td valign="Top"><SOAPCall>.encoding = <SOAPEncoding><br>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="Top">Associate a specific schema collection with all associated
|
||||
encodings<br>
|
||||
</td>
|
||||
<td valign="Top"><SOAPEncoding>.schemaCollection = <SchemaCollection><br>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="Top">Load Schema files containing additional schema types
|
||||
to be used for encoding or decoding<br>
|
||||
</td>
|
||||
<td valign="Top"><SchemaLoader>.load("<schema URI>")<br>
|
||||
<br>
|
||||
<SchemaLoader>.loadAsync("<schemaURI>", <completion function>)<br>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="Top">Directly get or set the XML content associated with
|
||||
a message block as a DOM Element<br>
|
||||
</td>
|
||||
<td valign="Top"><SOAPParameter>.element<br>
|
||||
// or<br>
|
||||
<SOAPHeaderBlock>.element<br>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="Top">Add or replace the encoders or decoders within the
|
||||
particular encoding<br>
|
||||
</td>
|
||||
<td valign="Top"><SOAPEncoding>.defaultEncoder = <SOAPEncoder><br>
|
||||
// or<br>
|
||||
<SOAPEncoding>.defaultDecoder = <SOAPDecoder><br>
|
||||
// or<br>
|
||||
<SOAPEncoding>.setEncoder("<namespaceURI>#<name>",<SOAPEncoder>)<br>
|
||||
// or<br>
|
||||
<SOAPEncoding>.setDecoder("<namespaceURI>#<name>",<SOAPDecoder>)<br>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="Top">Create an alternative encoding for use on specific
|
||||
messages<br>
|
||||
</td>
|
||||
<td valign="Top"><variable> = <SOAPEncoding>.getAssociatedEncoding("<namespaceURI>")<br>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="Top">Register modified or alternative encodings, making
|
||||
them automatically available to all SOAP scripts in the system<br>
|
||||
</td>
|
||||
<td valign="Top"><new encoding>.js<br>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="Top">Mark the call with a verifySourceHeader, if the server
|
||||
permits it, so the browser needs less risky privilege and trust for the script<br>
|
||||
</td>
|
||||
<td valign="Top"><SOAPCall>.verifySourceHeader = true<br>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="Top">Request risky privileges within a local or signed
|
||||
script to make an unverified SOAP calls to other domains<br>
|
||||
</td>
|
||||
<td valign="Top">netscape.security.PrivilegeManager.enablePrivilege("UniversalBrowserRead")<br>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="Top">Modify the security settings in the preferences file,
|
||||
allowing some domains to make risky SOAP calls without restriction</td>
|
||||
<td valign="Top">all.js: pref("<some domain>.SOAPCall.invoke","allAccess");<br>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="Top">Register alternative transport mechanisms, providing
|
||||
alternative transports to all SOAP scripts in the system<br>
|
||||
</td>
|
||||
<td valign="Top"><new transport>.js<br>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<h3>Additional Sources for Expert Operations</h3>
|
||||
For JS objects, source expressions can generally be placed on the right-side
|
||||
of an assignment (equals) operator to get an object of the listed type.<br>
|
||||
<br>
|
||||
<table cellpadding="2" cellspacing="2" border="1" width="100%">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td valign="Top">Object or File<br>
|
||||
</td>
|
||||
<td valign="Top">Additional Objects of Type Found Here<br>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="Top">SOAParameter<br>
|
||||
</td>
|
||||
<td valign="Top"><SOAPCall>.getParameters(<true if not rpc-style>,
|
||||
{}) // (if encoded)<br>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="Top">SOAPHeaderBlock<br>
|
||||
</td>
|
||||
<td valign="Top"><SOAPCall>.getHeaderBlocks({}) // (if encoded)<br>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="Top">SOAPEncoding<br>
|
||||
</td>
|
||||
<td valign="Top">new SOAPEncoding()<br>
|
||||
// or<br>
|
||||
<SOAPCall>.encoding // (if encoded)<br>
|
||||
// or<br>
|
||||
<SOAPResponse>.encoding<br>
|
||||
// or<br>
|
||||
<SOAPEncoding>.getAssociatedEncoding("<namespaceURI>",<true
|
||||
to create>)<br>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="Top">SOAPEncoder<br>
|
||||
</td>
|
||||
<td valign="Top"><Suitable Javascript function <New DOM Element>
|
||||
= <function name>(<SOAPEncoding>, <value>, <namespaceURI>,
|
||||
<name>, <SchemaType>, <SOAPAttachments>, <Parent DOM
|
||||
Element> )><br>
|
||||
// or<br>
|
||||
<SOAPEncoding>.defaultEncoder<br>
|
||||
// or<br>
|
||||
<SOAPEncoding>.getEncoder("<namespaceURI>#<name>")<br>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="Top">SOAPDecoder<br>
|
||||
</td>
|
||||
<td valign="Top"><Suitable Javascript function <value> = <function
|
||||
name>(<SOAPEncoding>, <DOM Element>, <SchemaType>, <SOAPAttachments>)><br>
|
||||
// or<br>
|
||||
<SOAPEncoding>.defaultDecoder<br>
|
||||
// or<br>
|
||||
<SOAPEncoding>.getDecoder("<namespaceURI>#<name>")<br>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="Top">SchemaLoader<br>
|
||||
</td>
|
||||
<td valign="Top"><SchemaCollection><br>
|
||||
// or<br>
|
||||
new SchemaLoader()<br>
|
||||
// or<br>
|
||||
<SOAPEncoding>.schemaCollection<br>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="Top">SchemaCollection<br>
|
||||
</td>
|
||||
<td valign="Top"><SchemaLoader><br>
|
||||
// or<br>
|
||||
new SchemaLoader()<br>
|
||||
// or<br>
|
||||
<SOAPEncoding>.schemaCollection<br>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="Top">SchemaType<br>
|
||||
</td>
|
||||
<td valign="Top"><SchemaCollection>.getType("<name>", "<namespaceURI>")<br>
|
||||
// or<br>
|
||||
<SOAPParameter>.schemaType<br>
|
||||
// or<br>
|
||||
<SOAPHeaderBlock>.schemaType<br>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="Top">SOAPCallCompletion<br>
|
||||
</td>
|
||||
<td valign="Top"><SOAPCall>.asyncInvoke(<SOAPResponseListener>)<br>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="Top">all.js<br>
|
||||
</td>
|
||||
<td valign="Top">In default/pref directory<br>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="Top"><new encoding>.js<br>
|
||||
</td>
|
||||
<td valign="Top">In components directory<br>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="Top"><new transport>.js<br>
|
||||
</td>
|
||||
<td valign="Top">In components directory<br>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="Top">netscape.security.PrivilegeManager<br>
|
||||
</td>
|
||||
<td valign="Top">Globally-available object in Javascript</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<h2>Future Features</h2>
|
||||
<h3>High-Level Access to SOAP</h3>
|
||||
Although a SOAP call can generally be accomplished using this API in a few
|
||||
dozen lines, rather than having to manually attach all the type information
|
||||
to the call and set and retrieve the parameters from arrays of blocks, WSDL
|
||||
is a standard that describes how all of this should occur with no manual
|
||||
type and argument setup required. An implementation is underway that
|
||||
instantiates web service proxies complete with appropriate xpconnect interfaces
|
||||
by simply loading and using information out of a WSDL file. The proxy's
|
||||
interface has dynamically-generated methods named appropriately to match
|
||||
the services described in the WSDL file which accept arguments of the appropriate
|
||||
data types and call the appropriate low-level SOAP functions with the appropriate
|
||||
type information, making it even simpler not only to invoke services from
|
||||
Javascript code, but to associate appropriate schema types loaded from the
|
||||
WSDL file with the arguments. This is not available in the first release.<br>
|
||||
<h3> </h3>
|
||||
<h3>Arbitrary Graphs of Data</h3>
|
||||
The SOAP specification allows objects to be passed as arguments which may
|
||||
have originally referenced other objects that are not owned in a pure hierarchy.
|
||||
This is represented by using an href attribute. Due to the problems
|
||||
with leaking reference counts in COM objects with cyclic references, this
|
||||
has not been implemented yet. Also, the output of a cyclicly-referencing
|
||||
set of objects has not been implemented. Incoming objects that do not
|
||||
reference cyclicly currently create separate copies for each reference to
|
||||
an object, and with cycles will probably never complete. On input,
|
||||
hrefs are currently ignored. In the future it may be possible to solve
|
||||
this and transmit and receive arbitrarily-referencing objects, but the solution
|
||||
is more complex than just using weak references.<br>
|
||||
<h3>SOAP With Attachments</h3>
|
||||
Many clients and servers now support automatically transmitting large Mime
|
||||
with a SOAP message by encapsulating it in MIME, DIME, or other enveloping
|
||||
formats. This has been anticipated in the APIs, but the SOAPAttachments
|
||||
API is currently a placeholder for this future feature which is not yet implemented.<br>
|
||||
<h2>Samples and Tests</h2>
|
||||
Tests are available which can be used as samples...<br>
|
||||
<br>
|
||||
If the samples are inadequate, look at the IDL files at...<br>
|
||||
<br>
|
||||
A test server exists at .... where I will put up relevant tests anyone submits...<br>
|
||||
<br>
|
||||
Bugs can be reported at...<br>
|
||||
<br>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,550 @@
|
|||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="content-type" content="text/html; charset=ISO-8859-1">
|
||||
<title>Soap Scripts in Mozilla</title>
|
||||
</head>
|
||||
<body>
|
||||
<div align="Center">
|
||||
<h1>SOAP Scripts in Mozilla</h1>
|
||||
<font color="#999999">February 16, 2002</font><br>
|
||||
<h3><font color="#999999">Ray Whitmer</font></h3>
|
||||
<h2><font color="#666666">Abstract</font></h2>
|
||||
<div align="Left"><font color="#000000">Microsoft and others have advocated
|
||||
SOAP as a way to encode and exchange public data structures between agents
|
||||
on the web. The browser client is the most universal web agent in existence,
|
||||
and Javascript is the standard, interoperable way of scripting browsers.
|
||||
Scriptable SOAP in browsers gives clients and servers more to say to each
|
||||
other through existing http-xml services, providing scripts with persistence,
|
||||
database, and access to other web services not tied to the request and response
|
||||
cycles of the HTML-based user interface. Web data structures, exchanged
|
||||
in a platform-neutral way, should become as fundamental to web agents as
|
||||
web content is today. The key to this is a tight binding to the natural
|
||||
data of Javascript so that the script can simply use the data instead of
|
||||
tediously encoding and extracting the data from the XML.</font><br>
|
||||
<h2>SOAP Services</h2>
|
||||
There are a number of sources for services available on the web being set
|
||||
up, such as XMethods. Apache supports modules for SOAP that this author has
|
||||
used to author services for purposes of testing and entertainment.
|
||||
Once it is set up, it is as simple as writing a function in Javascript, Java,
|
||||
or any other of a number of supported languages and then writing a simple
|
||||
service description in XML or submitting a form to deploy the service.
|
||||
There are toolkits available from Microsoft and other webserver providers
|
||||
for authoring such services as well.<br>
|
||||
<h2>SOAP Blocks</h2>
|
||||
<h3>Parameters<br>
|
||||
</h3>
|
||||
SOAP-based services exchange message envelopes which contain blocks of XML
|
||||
data roughly corresponding to the parameters of a service call. When
|
||||
an rpc-style message is exchanged, blocks representing the regular parameter
|
||||
blocks are placed inside an element which identifies the object and method
|
||||
being invoked, which is placed inside the body. In a non-RPC message,
|
||||
the blocks are placed directly inside the body instead of under the method
|
||||
element. <br>
|
||||
<h3>Header Blocks<br>
|
||||
</h3>
|
||||
Blocks which are optional or are independently added or processed are placed
|
||||
inside the header with an assigned role and specially marked if the recipient
|
||||
is required to understand them.<br>
|
||||
<h3>Encodings<br>
|
||||
</h3>
|
||||
Interpretation of each block depends upon the encoding that was used, which
|
||||
is clearly specified in the message. If the standard SOAP encoding
|
||||
is used, then XML Schema types used to interpret the data within each block.<br>
|
||||
<h2>Using the Low-Level SOAP API</h2>
|
||||
To use the low-level API, the user creates a SOAPCall object, encodes the
|
||||
function call with a list of headers and regular parameters, and invokes the
|
||||
call, which returns a response which contains the results of the service call
|
||||
including a fault generated by the service which processed the message, output
|
||||
parameters, and/or header blocks. If the call is invoked asynchronously,
|
||||
then a function is given which receives the response when it arrives from
|
||||
the remote service.<br>
|
||||
<br>
|
||||
Besides Javascript, the below-described operations should also generally
|
||||
work for other xpconnect-supported languages in Mozilla such as C++/XPCOM
|
||||
and Python, because language-independent cross-platform interfaces were used.<br>
|
||||
<br>
|
||||
Object names or descriptions contained in angle brackets represent any object
|
||||
of the named or described type. Quoted angle brackets indicate a suitable
|
||||
string of the named or described value type.<br>
|
||||
<h3>Basic Operations<br>
|
||||
</h3>
|
||||
For most simple use cases, basic operations is all the user needs to do.<br>
|
||||
<br>
|
||||
<table cellpadding="2" cellspacing="2" border="1" width="100%">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td valign="Top">Basic Operation<br>
|
||||
</td>
|
||||
<td valign="Top">Ways to Access<br>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="Top">Set a Javascript value or object as the value of a
|
||||
message block<br>
|
||||
</td>
|
||||
<td valign="Top"><variable> = new SOAPParameter(<value>)<br>
|
||||
// or<br>
|
||||
<variable> = new SOAPHeader(<value>)<br>
|
||||
// or<br>
|
||||
<SOAPParameter>.value = <value><br>
|
||||
or<br>
|
||||
<SOAPHeaderBlock>.value = <value><br>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="Top">Get or set header blocks or parameters in a Javascript
|
||||
array<br>
|
||||
</td>
|
||||
<td valign="Top"><Array>[]<br>
|
||||
// or<br>
|
||||
new Array(<block>[,...]);<br>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="Top">Associate the arrays of header blocks and parameters
|
||||
with a message<br>
|
||||
</td>
|
||||
<td valign="Top"><SOAPCall>.encode(<0 or 1 for 1.1 or 1.2>,
|
||||
"<method>", "<object namespace>", <header count>, <headers>,
|
||||
<parameter count>, <parameters>)<br>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="Top">Invoke call (send call message and receive response
|
||||
message)<br>
|
||||
</td>
|
||||
<td valign="Top"><SOAPCall>.invoke()<br>
|
||||
// or<br>
|
||||
<SOAPCall>.asyncInvoke(<SOAPResponseListener>)<br>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="Top">Get the response's fault, if any<br>
|
||||
</td>
|
||||
<td valign="Top"><SOAPResponse>.fault<br>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="Top">Get the arrays of blocks from the response<br>
|
||||
</td>
|
||||
<td valign="Top"><variable> = <SOAPResponse>.getParameters(<true
|
||||
if not rpc-style>, {})<br>
|
||||
// or<br>
|
||||
<variable> = <SOAPResponse>.getHeaderBlocks({})<br>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="Top">Get a Javascript value or object from a response message
|
||||
block<br>
|
||||
</td>
|
||||
<td valign="Top"><variable> = <SOAPParameter>.value<br>
|
||||
// or<br>
|
||||
<variable> = <SOAPHeaderBlock>.value<br>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<h3>Sources of Objects for Basic Operations</h3>
|
||||
Source expressions can generally be placed on the right-side of an assignment
|
||||
(equals) operator to get an object of the listed type.<br>
|
||||
<br>
|
||||
<table cellpadding="2" cellspacing="2" border="1" width="100%">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td valign="Top">Basic Object Types<br>
|
||||
</td>
|
||||
<td valign="Top">Objects of Type Found Here<br>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="Top">SOAPParameter<br>
|
||||
</td>
|
||||
<td valign="Top">new SOAPParameter()<br>
|
||||
// or<br>
|
||||
<SOAPResponse>.getParameters(<true if not rpc-style>, {})<br>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="Top">SOAPHeaderBlock<br>
|
||||
</td>
|
||||
<td valign="Top">new SOAPHeaderBlock()<br>
|
||||
// or<br>
|
||||
SOAPResponse.getHeaderBlocks({})<br>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="Top">SOAPCall<br>
|
||||
</td>
|
||||
<td valign="Top">new SOAPCall()<br>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="Top">SOAPResponse<br>
|
||||
</td>
|
||||
<td valign="Top"><SOAPCall>.invoke()<br>
|
||||
// or<br>
|
||||
<SOAPCall>.asyncInvoke(<SOAPResponseListener>) // SOAPResponse
|
||||
delivered to listener<br>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="Top">SOAPResponseListener<br>
|
||||
</td>
|
||||
<td valign="Top"><Function accepting (<SOAPResponse>, <SOAPCall>,
|
||||
<status>)><br>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="Top">SOAPFault<br>
|
||||
</td>
|
||||
<td valign="Top"><SOAPResponse>.fault<br>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<br>
|
||||
<h3>Expert Operations -- To be Skipped by the Bleary-Eyed<br>
|
||||
</h3>
|
||||
When the default encoding, decoding, and handling is not adequate, the user
|
||||
has access to a variety of additional JS-accessible mechanisms to control
|
||||
the encoding and decoding of messages.<br>
|
||||
<br>
|
||||
<table cellpadding="2" cellspacing="2" border="1" width="100%">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td valign="Top">Operation<br>
|
||||
</td>
|
||||
<td valign="Top">Ways to Access<br>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="Top">Set or get the name and namespaceURI of a message
|
||||
block<br>
|
||||
</td>
|
||||
<td valign="Top"><variable> = new SOAPParameter(<value>,
|
||||
"<name>", "<namespaceURI>")<br>
|
||||
// or<br>
|
||||
<SOAPParameter>.name<br>
|
||||
// or<br>
|
||||
<SOAPParameter>.namespaceURI<br>
|
||||
// or<br>
|
||||
<variable> = new SOAPHeaderBlock(<value>, "<name>", "<namespaceURI>")<br>
|
||||
// or<br>
|
||||
<SOAPHeaderBlock>.name<br>
|
||||
// or<br>
|
||||
<SOAPHeaderBlock>.namespaceURI<br>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="Top">Mark / check role URI of header block<br>
|
||||
</td>
|
||||
<td valign="Top"><SOAPHeaderBlock>.actorURI<br>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="Top">Mark / check boolean value whether header must be
|
||||
understood by recipient or the message should be rejected<br>
|
||||
</td>
|
||||
<td valign="Top"><SOAPHeaderBlock>.mustUnderstand<br>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="Top">Check the actual SOAP version of an encoded message.<br>
|
||||
</td>
|
||||
<td valign="Top"><SOAPCall>.version<br>
|
||||
// or<br>
|
||||
<SOAPResponse>.version<br>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="Top">Abort an in-progress asynchronous call<br>
|
||||
</td>
|
||||
<td valign="Top"><SOAPCallCompletion>.abort()<br>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="Top">Map or unmap alias schema target URIs to be used --
|
||||
as SOAP 1.1 types are aliased 1.2 types<br>
|
||||
</td>
|
||||
<td valign="Top"><SOAPEncoding>.mapSchemaURI("<external URI>",
|
||||
"<internal URI>", <true to alias output>)<br>
|
||||
// or<br>
|
||||
<SOAPEncoding>.unmapSchemaURI("<external URI>")<br>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="Top">Associate a specific XML schema type (SchemaType)
|
||||
with the block to govern encoding or decoding<br>
|
||||
</td>
|
||||
<td valign="Top"><variable> = <SchemaCollection>.getType("<name>",
|
||||
"<namespaceURI>")<br>
|
||||
// and then<br>
|
||||
<variable2> = new SOAPParameter(<value>, "<name>", "<namespaceURI>",
|
||||
<SchemaType>)<br>
|
||||
// or<br>
|
||||
<SOAPParameter>.schemaType = <variable><br>
|
||||
// or<br>
|
||||
<variable2> = new SOAPHeaderBlock(<value>, "<name>", "<namespaceURI>",
|
||||
<SchemaType>)<br>
|
||||
// or<br>
|
||||
<SOAPHeaderBlock>.schemaType = <variable><br>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="Top">Associate a specific encoding with the call to govern
|
||||
encoding or decoding<br>
|
||||
</td>
|
||||
<td valign="Top"><SOAPCall>.encoding = <SOAPEncoding><br>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="Top">Associate a specific schema collection with all associated
|
||||
encodings<br>
|
||||
</td>
|
||||
<td valign="Top"><SOAPEncoding>.schemaCollection = <SchemaCollection><br>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="Top">Load Schema files containing additional schema types
|
||||
to be used for encoding or decoding<br>
|
||||
</td>
|
||||
<td valign="Top"><SchemaLoader>.load("<schema URI>")<br>
|
||||
<br>
|
||||
<SchemaLoader>.loadAsync("<schemaURI>", <completion function>)<br>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="Top">Directly get or set the XML content associated with
|
||||
a message block as a DOM Element<br>
|
||||
</td>
|
||||
<td valign="Top"><SOAPParameter>.element<br>
|
||||
// or<br>
|
||||
<SOAPHeaderBlock>.element<br>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="Top">Add or replace the encoders or decoders within the
|
||||
particular encoding<br>
|
||||
</td>
|
||||
<td valign="Top"><SOAPEncoding>.defaultEncoder = <SOAPEncoder><br>
|
||||
// or<br>
|
||||
<SOAPEncoding>.defaultDecoder = <SOAPDecoder><br>
|
||||
// or<br>
|
||||
<SOAPEncoding>.setEncoder("<namespaceURI>#<name>",<SOAPEncoder>)<br>
|
||||
// or<br>
|
||||
<SOAPEncoding>.setDecoder("<namespaceURI>#<name>",<SOAPDecoder>)<br>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="Top">Create an alternative encoding for use on specific
|
||||
messages<br>
|
||||
</td>
|
||||
<td valign="Top"><variable> = <SOAPEncoding>.getAssociatedEncoding("<namespaceURI>")<br>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="Top">Register modified or alternative encodings, making
|
||||
them automatically available to all SOAP scripts in the system<br>
|
||||
</td>
|
||||
<td valign="Top"><new encoding>.js<br>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="Top">Mark the call with a verifySourceHeader, if the server
|
||||
permits it, so the browser needs less risky privilege and trust for the script<br>
|
||||
</td>
|
||||
<td valign="Top"><SOAPCall>.verifySourceHeader = true<br>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="Top">Request risky privileges within a local or signed
|
||||
script to make an unverified SOAP calls to other domains<br>
|
||||
</td>
|
||||
<td valign="Top">netscape.security.PrivilegeManager.enablePrivilege("UniversalBrowserRead")<br>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="Top">Modify the security settings in the preferences file,
|
||||
allowing some domains to make risky SOAP calls without restriction</td>
|
||||
<td valign="Top">all.js: pref("<some domain>.SOAPCall.invoke","allAccess");<br>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="Top">Register alternative transport mechanisms, providing
|
||||
alternative transports to all SOAP scripts in the system<br>
|
||||
</td>
|
||||
<td valign="Top"><new transport>.js<br>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<h3>Additional Sources for Expert Operations</h3>
|
||||
For JS objects, source expressions can generally be placed on the right-side
|
||||
of an assignment (equals) operator to get an object of the listed type.<br>
|
||||
<br>
|
||||
<table cellpadding="2" cellspacing="2" border="1" width="100%">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td valign="Top">Object or File<br>
|
||||
</td>
|
||||
<td valign="Top">Additional Objects of Type Found Here<br>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="Top">SOAParameter<br>
|
||||
</td>
|
||||
<td valign="Top"><SOAPCall>.getParameters(<true if not rpc-style>,
|
||||
{}) // (if encoded)<br>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="Top">SOAPHeaderBlock<br>
|
||||
</td>
|
||||
<td valign="Top"><SOAPCall>.getHeaderBlocks({}) // (if encoded)<br>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="Top">SOAPEncoding<br>
|
||||
</td>
|
||||
<td valign="Top">new SOAPEncoding()<br>
|
||||
// or<br>
|
||||
<SOAPCall>.encoding // (if encoded)<br>
|
||||
// or<br>
|
||||
<SOAPResponse>.encoding<br>
|
||||
// or<br>
|
||||
<SOAPEncoding>.getAssociatedEncoding("<namespaceURI>",<true
|
||||
to create>)<br>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="Top">SOAPEncoder<br>
|
||||
</td>
|
||||
<td valign="Top"><Suitable Javascript function <New DOM Element>
|
||||
= <function name>(<SOAPEncoding>, <value>, <namespaceURI>,
|
||||
<name>, <SchemaType>, <SOAPAttachments>, <Parent DOM
|
||||
Element> )><br>
|
||||
// or<br>
|
||||
<SOAPEncoding>.defaultEncoder<br>
|
||||
// or<br>
|
||||
<SOAPEncoding>.getEncoder("<namespaceURI>#<name>")<br>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="Top">SOAPDecoder<br>
|
||||
</td>
|
||||
<td valign="Top"><Suitable Javascript function <value> = <function
|
||||
name>(<SOAPEncoding>, <DOM Element>, <SchemaType>, <SOAPAttachments>)><br>
|
||||
// or<br>
|
||||
<SOAPEncoding>.defaultDecoder<br>
|
||||
// or<br>
|
||||
<SOAPEncoding>.getDecoder("<namespaceURI>#<name>")<br>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="Top">SchemaLoader<br>
|
||||
</td>
|
||||
<td valign="Top"><SchemaCollection><br>
|
||||
// or<br>
|
||||
new SchemaLoader()<br>
|
||||
// or<br>
|
||||
<SOAPEncoding>.schemaCollection<br>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="Top">SchemaCollection<br>
|
||||
</td>
|
||||
<td valign="Top"><SchemaLoader><br>
|
||||
// or<br>
|
||||
new SchemaLoader()<br>
|
||||
// or<br>
|
||||
<SOAPEncoding>.schemaCollection<br>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="Top">SchemaType<br>
|
||||
</td>
|
||||
<td valign="Top"><SchemaCollection>.getType("<name>", "<namespaceURI>")<br>
|
||||
// or<br>
|
||||
<SOAPParameter>.schemaType<br>
|
||||
// or<br>
|
||||
<SOAPHeaderBlock>.schemaType<br>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="Top">SOAPCallCompletion<br>
|
||||
</td>
|
||||
<td valign="Top"><SOAPCall>.asyncInvoke(<SOAPResponseListener>)<br>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="Top">all.js<br>
|
||||
</td>
|
||||
<td valign="Top">In default/pref directory<br>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="Top"><new encoding>.js<br>
|
||||
</td>
|
||||
<td valign="Top">In components directory<br>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="Top"><new transport>.js<br>
|
||||
</td>
|
||||
<td valign="Top">In components directory<br>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="Top">netscape.security.PrivilegeManager<br>
|
||||
</td>
|
||||
<td valign="Top">Globally-available object in Javascript</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<h2>Future Features</h2>
|
||||
<h3>High-Level Access to SOAP</h3>
|
||||
Although a SOAP call can generally be accomplished using this API in a few
|
||||
dozen lines, rather than having to manually attach all the type information
|
||||
to the call and set and retrieve the parameters from arrays of blocks, WSDL
|
||||
is a standard that describes how all of this should occur with no manual
|
||||
type and argument setup required. An implementation is underway that
|
||||
instantiates web service proxies complete with appropriate xpconnect interfaces
|
||||
by simply loading and using information out of a WSDL file. The proxy's
|
||||
interface has dynamically-generated methods named appropriately to match
|
||||
the services described in the WSDL file which accept arguments of the appropriate
|
||||
data types and call the appropriate low-level SOAP functions with the appropriate
|
||||
type information, making it even simpler not only to invoke services from
|
||||
Javascript code, but to associate appropriate schema types loaded from the
|
||||
WSDL file with the arguments. This is not available in the first release.<br>
|
||||
<h3> </h3>
|
||||
<h3>Arbitrary Graphs of Data</h3>
|
||||
The SOAP specification allows objects to be passed as arguments which may
|
||||
have originally referenced other objects that are not owned in a pure hierarchy.
|
||||
This is represented by using an href attribute. Due to the problems
|
||||
with leaking reference counts in COM objects with cyclic references, this
|
||||
has not been implemented yet. Also, the output of a cyclicly-referencing
|
||||
set of objects has not been implemented. Incoming objects that do not
|
||||
reference cyclicly currently create separate copies for each reference to
|
||||
an object, and with cycles will probably never complete. On input,
|
||||
hrefs are currently ignored. In the future it may be possible to solve
|
||||
this and transmit and receive arbitrarily-referencing objects, but the solution
|
||||
is more complex than just using weak references.<br>
|
||||
<h3>SOAP With Attachments</h3>
|
||||
Many clients and servers now support automatically transmitting large Mime
|
||||
with a SOAP message by encapsulating it in MIME, DIME, or other enveloping
|
||||
formats. This has been anticipated in the APIs, but the SOAPAttachments
|
||||
API is currently a placeholder for this future feature which is not yet implemented.<br>
|
||||
<h2>Samples and Tests</h2>
|
||||
Tests are available which can be used as samples...<br>
|
||||
<br>
|
||||
If the samples are inadequate, look at the IDL files at...<br>
|
||||
<br>
|
||||
A test server exists at .... where I will put up relevant tests anyone submits...<br>
|
||||
<br>
|
||||
Bugs can be reported at...<br>
|
||||
<br>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
Загрузка…
Ссылка в новой задаче