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