1*2a97ec55SAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3*2a97ec55SAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4*2a97ec55SAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5*2a97ec55SAndrew Rist  * distributed with this work for additional information
6*2a97ec55SAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7*2a97ec55SAndrew Rist  * to you under the Apache License, Version 2.0 (the
8*2a97ec55SAndrew Rist  * "License"); you may not use this file except in compliance
9*2a97ec55SAndrew Rist  * with the License.  You may obtain a copy of the License at
10*2a97ec55SAndrew Rist  *
11*2a97ec55SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12*2a97ec55SAndrew Rist  *
13*2a97ec55SAndrew Rist  * Unless required by applicable law or agreed to in writing,
14*2a97ec55SAndrew Rist  * software distributed under the License is distributed on an
15*2a97ec55SAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*2a97ec55SAndrew Rist  * KIND, either express or implied.  See the License for the
17*2a97ec55SAndrew Rist  * specific language governing permissions and limitations
18*2a97ec55SAndrew Rist  * under the License.
19*2a97ec55SAndrew Rist  *
20*2a97ec55SAndrew Rist  *************************************************************/
21*2a97ec55SAndrew Rist 
22*2a97ec55SAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_extensions.hxx"
26cdf0e10cSrcweir 
27cdf0e10cSrcweir #include "soapsender.hxx"
28cdf0e10cSrcweir #include <com/sun/star/ucb/XSimpleFileAccess.hpp>
29cdf0e10cSrcweir #include <com/sun/star/uno/RuntimeException.hpp>
30cdf0e10cSrcweir #include <com/sun/star/util/XURLTransformer.hpp>
31cdf0e10cSrcweir #include <com/sun/star/io/XTempFile.hpp>
32cdf0e10cSrcweir #include <com/sun/star/io/XOutputStream.hpp>
33cdf0e10cSrcweir #include <com/sun/star/io/XInputStream.hpp>
34cdf0e10cSrcweir #include <osl/socket.hxx>
35cdf0e10cSrcweir #include <rtl/strbuf.hxx>
36cdf0e10cSrcweir #include <boost/shared_ptr.hpp>
37cdf0e10cSrcweir 
38cdf0e10cSrcweir 
39cdf0e10cSrcweir using namespace com::sun::star::uno;
40cdf0e10cSrcweir using namespace com::sun::star::lang;
41cdf0e10cSrcweir using namespace com::sun::star::io;
42cdf0e10cSrcweir using boost::shared_ptr;
43cdf0e10cSrcweir using com::sun::star::io::XTempFile;
44cdf0e10cSrcweir using com::sun::star::ucb::XSimpleFileAccess;
45cdf0e10cSrcweir using com::sun::star::util::URL;
46cdf0e10cSrcweir using com::sun::star::util::XURLTransformer;
47cdf0e10cSrcweir using osl::ConnectorSocket;
48cdf0e10cSrcweir using rtl::OString;
49cdf0e10cSrcweir using rtl::OUString;
50cdf0e10cSrcweir using rtl::OStringBuffer;
51cdf0e10cSrcweir 
52cdf0e10cSrcweir 
53cdf0e10cSrcweir namespace
54cdf0e10cSrcweir {
getHttpPostHeader(OString path,sal_Int32 length)55cdf0e10cSrcweir     static OString getHttpPostHeader(OString path, sal_Int32 length)
56cdf0e10cSrcweir     {
57cdf0e10cSrcweir         OStringBuffer result =
58cdf0e10cSrcweir             "POST " + path + " HTTP/1.0\r\n"
59cdf0e10cSrcweir             "Content-Type: text/xml; charset=\"utf-8\"\r\n"
60cdf0e10cSrcweir             "Content-Length: ";
61cdf0e10cSrcweir         result.append(length);
62cdf0e10cSrcweir         result.append("\r\nSOAPAction: \"\"\r\n\r\n");
63cdf0e10cSrcweir         return result.makeStringAndClear();
64cdf0e10cSrcweir     };
65cdf0e10cSrcweir }
66cdf0e10cSrcweir 
67cdf0e10cSrcweir namespace oooimprovement
68cdf0e10cSrcweir {
SoapSender(const Reference<XMultiServiceFactory> sf,const OUString & url)69cdf0e10cSrcweir     SoapSender::SoapSender(const Reference<XMultiServiceFactory> sf, const OUString& url)
70cdf0e10cSrcweir         : m_ServiceFactory(sf)
71cdf0e10cSrcweir         , m_Url(url)
72cdf0e10cSrcweir     { }
73cdf0e10cSrcweir 
send(const SoapRequest & request) const74cdf0e10cSrcweir     void SoapSender::send(const SoapRequest& request) const
75cdf0e10cSrcweir     {
76cdf0e10cSrcweir         Reference<XTempFile> temp_file(
77cdf0e10cSrcweir             m_ServiceFactory->createInstance(OUString::createFromAscii("com.sun.star.io.TempFile")),
78cdf0e10cSrcweir             UNO_QUERY_THROW);
79cdf0e10cSrcweir         Reference<XSimpleFileAccess> file_access(
80cdf0e10cSrcweir             m_ServiceFactory->createInstance(OUString::createFromAscii("com.sun.star.ucb.SimpleFileAccess")),
81cdf0e10cSrcweir             UNO_QUERY_THROW);
82cdf0e10cSrcweir         Reference<XURLTransformer> url_trans(
83cdf0e10cSrcweir             m_ServiceFactory->createInstance(OUString::createFromAscii("com.sun.star.util.URLTransformer")),
84cdf0e10cSrcweir             UNO_QUERY_THROW);
85cdf0e10cSrcweir 
86cdf0e10cSrcweir         // writing request to tempfile
87cdf0e10cSrcweir         {
88cdf0e10cSrcweir             Reference<XOutputStream> temp_stream = temp_file->getOutputStream();
89cdf0e10cSrcweir             request.writeTo(temp_stream);
90cdf0e10cSrcweir             temp_stream->flush();
91cdf0e10cSrcweir             temp_stream->closeOutput();
92cdf0e10cSrcweir         }
93cdf0e10cSrcweir 
94cdf0e10cSrcweir         // parse Url
95cdf0e10cSrcweir         URL url;
96cdf0e10cSrcweir         {
97cdf0e10cSrcweir             url.Complete = m_Url;
98cdf0e10cSrcweir             url_trans->parseStrict(url);
99cdf0e10cSrcweir         }
100cdf0e10cSrcweir 
101cdf0e10cSrcweir         // connect socket
102cdf0e10cSrcweir         shared_ptr<ConnectorSocket> socket(new ConnectorSocket(osl_Socket_FamilyInet, osl_Socket_ProtocolIp, osl_Socket_TypeStream));
103cdf0e10cSrcweir         {
104cdf0e10cSrcweir             ::osl::SocketAddr addr(url.Server, url.Port);
105cdf0e10cSrcweir             oslSocketResult result = socket->connect(addr);
106cdf0e10cSrcweir             if(result != osl_Socket_Ok)
107cdf0e10cSrcweir                 throw RuntimeException(
108cdf0e10cSrcweir                     OUString::createFromAscii("unable to connect to SOAP server"),
109cdf0e10cSrcweir                     Reference<XInterface>());
110cdf0e10cSrcweir         }
111cdf0e10cSrcweir 
112cdf0e10cSrcweir         // send header
113cdf0e10cSrcweir         {
114cdf0e10cSrcweir             OStringBuffer path_on_server =
115cdf0e10cSrcweir                 OUStringToOString(url.Path, RTL_TEXTENCODING_ASCII_US) +
116cdf0e10cSrcweir                 OUStringToOString(url.Name, RTL_TEXTENCODING_ASCII_US);
117cdf0e10cSrcweir             const OString header = getHttpPostHeader(path_on_server.makeStringAndClear(), file_access->getSize(temp_file->getUri()));
118cdf0e10cSrcweir             if(socket->write(header.getStr(), header.getLength()) != static_cast<sal_Int32>(header.getLength()))
119cdf0e10cSrcweir                 throw RuntimeException(
120cdf0e10cSrcweir                     OUString::createFromAscii("error while sending HTTP header"),
121cdf0e10cSrcweir                     Reference<XInterface>());
122cdf0e10cSrcweir         }
123cdf0e10cSrcweir 
124cdf0e10cSrcweir         // send soap request
125cdf0e10cSrcweir         {
126cdf0e10cSrcweir             Reference<XInputStream> temp_stream = file_access->openFileRead(temp_file->getUri());
127cdf0e10cSrcweir             const sal_Int32 bufsize = 1024;
128cdf0e10cSrcweir             sal_Int32 bytes_read;
129cdf0e10cSrcweir             Sequence<sal_Int8> buf(bufsize);
130cdf0e10cSrcweir             char buf2[bufsize];
131cdf0e10cSrcweir             do
132cdf0e10cSrcweir             {
133cdf0e10cSrcweir                 bytes_read = temp_stream->readBytes(buf, bufsize);
134cdf0e10cSrcweir                 buf.realloc(bytes_read);
135cdf0e10cSrcweir                 for(sal_Int32 idx = 0; idx < bytes_read; idx++)
136cdf0e10cSrcweir                     buf2[idx] = buf[idx];
137cdf0e10cSrcweir                 if(socket->write(buf2, bytes_read) != bytes_read)
138cdf0e10cSrcweir                     throw RuntimeException(
139cdf0e10cSrcweir                         OUString::createFromAscii("error while sending SOAP request"),
140cdf0e10cSrcweir                         Reference<XInterface>());
141cdf0e10cSrcweir             } while(bytes_read == bufsize);
142cdf0e10cSrcweir         }
143cdf0e10cSrcweir 
144cdf0e10cSrcweir         // receive answer
145cdf0e10cSrcweir         {
146cdf0e10cSrcweir             const sal_Int32 bufsize = 1024;
147cdf0e10cSrcweir             char buf[bufsize];
148cdf0e10cSrcweir             sal_Int32 bytes_read = socket->read(buf, bufsize);
149cdf0e10cSrcweir             OString answer(buf, bytes_read);
150cdf0e10cSrcweir             const sal_Int32 returncode_start = answer.indexOf(' ');
151cdf0e10cSrcweir             if(returncode_start==-1 || !answer.copy(returncode_start, 4).equals(OString(" 200")))
152cdf0e10cSrcweir                 throw RuntimeException(
153cdf0e10cSrcweir                     OUString::createFromAscii("SOAP server returns a error"),
154cdf0e10cSrcweir                     Reference<XInterface>());
155cdf0e10cSrcweir         }
156cdf0e10cSrcweir     }
157cdf0e10cSrcweir }
158