Basic SOAP client, reworked transport streams.
[shibboleth/cpp-xmltooling.git] / xmltooling / soap / impl / SOAPClient.cpp
1 /*
2  *  Copyright 2001-2006 Internet2
3  * 
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 /**
18  * SOAPClient.cpp
19  * 
20  * Implements SOAP 1.1 messaging over a transport.
21  */
22
23 #include "internal.h"
24 #include "exceptions.h"
25 #include "soap/SOAP.h"
26 #include "soap/SOAPClient.h"
27 #include "util/XMLHelper.h"
28
29 #include <sstream>
30
31 using namespace soap11;
32 using namespace xmltooling;
33 using namespace std;
34
35 SOAPClient::~SOAPClient()
36 {
37     reset();
38 }
39
40 void SOAPClient::reset()
41 {
42     delete m_transport;
43     m_transport=NULL;
44 }
45
46 void SOAPClient::send(const Envelope* env, const KeyInfoSource& peer, const char* endpoint)
47 {
48     // Prepare a transport object.
49     const char* pch = strchr(endpoint,':');
50     if (!pch)
51         throw IOException("SOAP endpoint was not a URL.");
52     string scheme(endpoint, pch-endpoint);
53     m_transport = XMLToolingConfig::getConfig().SOAPTransportManager.newPlugin(scheme.c_str(), make_pair(&peer,endpoint));
54     prepareTransport(*m_transport);
55     
56     // Serialize envelope.
57     stringstream s;
58     XMLHelper::serialize(env->marshall(), s);
59     
60     // Send to peer.
61     m_transport->send(s);
62 }
63
64 Envelope* SOAPClient::receive()
65 {
66     if (!m_transport)
67         throw IOException("No call is active.");
68     
69     // If we can get the stream, then the call is still active.
70     istream& out = m_transport->receive();
71     if (!out)
72         return NULL;    // nothing yet
73     
74     // Parse and bind the document into an XMLObject.
75     DOMDocument* doc = (m_validate ? XMLToolingConfig::getConfig().getValidatingParser()
76         : XMLToolingConfig::getConfig().getParser()).parse(out); 
77     XercesJanitor<DOMDocument> janitor(doc);
78     auto_ptr<XMLObject> xmlObject(XMLObjectBuilder::buildOneFromElement(doc->getDocumentElement(), true));
79     janitor.release();
80
81     Envelope* env = dynamic_cast<Envelope*>(xmlObject.get());
82     if (!env)
83         throw IOException("Response was not a SOAP 1.1 Envelope.");
84     reset();
85     xmlObject.release();
86     return env;
87 }