1 /************************************************************************* 2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 3 * 4 * Copyright 2000, 2010 Oracle and/or its affiliates. 5 * 6 * OpenOffice.org - a multi-platform office productivity suite 7 * 8 * This file is part of OpenOffice.org. 9 * 10 * OpenOffice.org is free software: you can redistribute it and/or modify 11 * it under the terms of the GNU Lesser General Public License version 3 12 * only, as published by the Free Software Foundation. 13 * 14 * OpenOffice.org is distributed in the hope that it will be useful, 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 * GNU Lesser General Public License version 3 for more details 18 * (a copy is included in the LICENSE file that accompanied this code). 19 * 20 * You should have received a copy of the GNU Lesser General Public License 21 * version 3 along with OpenOffice.org. If not, see 22 * <http://www.openoffice.org/license.html> 23 * for a copy of the LGPLv3 License. 24 * 25 ************************************************************************/ 26 27 // MARKER(update_precomp.py): autogen include statement, do not remove 28 #include "precompiled_extensions.hxx" 29 30 #include "soapsender.hxx" 31 #include <com/sun/star/ucb/XSimpleFileAccess.hpp> 32 #include <com/sun/star/uno/RuntimeException.hpp> 33 #include <com/sun/star/util/XURLTransformer.hpp> 34 #include <com/sun/star/io/XTempFile.hpp> 35 #include <com/sun/star/io/XOutputStream.hpp> 36 #include <com/sun/star/io/XInputStream.hpp> 37 #include <osl/socket.hxx> 38 #include <rtl/strbuf.hxx> 39 #include <boost/shared_ptr.hpp> 40 41 42 using namespace com::sun::star::uno; 43 using namespace com::sun::star::lang; 44 using namespace com::sun::star::io; 45 using boost::shared_ptr; 46 using com::sun::star::io::XTempFile; 47 using com::sun::star::ucb::XSimpleFileAccess; 48 using com::sun::star::util::URL; 49 using com::sun::star::util::XURLTransformer; 50 using osl::ConnectorSocket; 51 using rtl::OString; 52 using rtl::OUString; 53 using rtl::OStringBuffer; 54 55 56 namespace 57 { 58 static OString getHttpPostHeader(OString path, sal_Int32 length) 59 { 60 OStringBuffer result = 61 "POST " + path + " HTTP/1.0\r\n" 62 "Content-Type: text/xml; charset=\"utf-8\"\r\n" 63 "Content-Length: "; 64 result.append(length); 65 result.append("\r\nSOAPAction: \"\"\r\n\r\n"); 66 return result.makeStringAndClear(); 67 }; 68 } 69 70 namespace oooimprovement 71 { 72 SoapSender::SoapSender(const Reference<XMultiServiceFactory> sf, const OUString& url) 73 : m_ServiceFactory(sf) 74 , m_Url(url) 75 { } 76 77 void SoapSender::send(const SoapRequest& request) const 78 { 79 Reference<XTempFile> temp_file( 80 m_ServiceFactory->createInstance(OUString::createFromAscii("com.sun.star.io.TempFile")), 81 UNO_QUERY_THROW); 82 Reference<XSimpleFileAccess> file_access( 83 m_ServiceFactory->createInstance(OUString::createFromAscii("com.sun.star.ucb.SimpleFileAccess")), 84 UNO_QUERY_THROW); 85 Reference<XURLTransformer> url_trans( 86 m_ServiceFactory->createInstance(OUString::createFromAscii("com.sun.star.util.URLTransformer")), 87 UNO_QUERY_THROW); 88 89 // writing request to tempfile 90 { 91 Reference<XOutputStream> temp_stream = temp_file->getOutputStream(); 92 request.writeTo(temp_stream); 93 temp_stream->flush(); 94 temp_stream->closeOutput(); 95 } 96 97 // parse Url 98 URL url; 99 { 100 url.Complete = m_Url; 101 url_trans->parseStrict(url); 102 } 103 104 // connect socket 105 shared_ptr<ConnectorSocket> socket(new ConnectorSocket(osl_Socket_FamilyInet, osl_Socket_ProtocolIp, osl_Socket_TypeStream)); 106 { 107 ::osl::SocketAddr addr(url.Server, url.Port); 108 oslSocketResult result = socket->connect(addr); 109 if(result != osl_Socket_Ok) 110 throw RuntimeException( 111 OUString::createFromAscii("unable to connect to SOAP server"), 112 Reference<XInterface>()); 113 } 114 115 // send header 116 { 117 OStringBuffer path_on_server = 118 OUStringToOString(url.Path, RTL_TEXTENCODING_ASCII_US) + 119 OUStringToOString(url.Name, RTL_TEXTENCODING_ASCII_US); 120 const OString header = getHttpPostHeader(path_on_server.makeStringAndClear(), file_access->getSize(temp_file->getUri())); 121 if(socket->write(header.getStr(), header.getLength()) != static_cast<sal_Int32>(header.getLength())) 122 throw RuntimeException( 123 OUString::createFromAscii("error while sending HTTP header"), 124 Reference<XInterface>()); 125 } 126 127 // send soap request 128 { 129 Reference<XInputStream> temp_stream = file_access->openFileRead(temp_file->getUri()); 130 const sal_Int32 bufsize = 1024; 131 sal_Int32 bytes_read; 132 Sequence<sal_Int8> buf(bufsize); 133 char buf2[bufsize]; 134 do 135 { 136 bytes_read = temp_stream->readBytes(buf, bufsize); 137 buf.realloc(bytes_read); 138 for(sal_Int32 idx = 0; idx < bytes_read; idx++) 139 buf2[idx] = buf[idx]; 140 if(socket->write(buf2, bytes_read) != bytes_read) 141 throw RuntimeException( 142 OUString::createFromAscii("error while sending SOAP request"), 143 Reference<XInterface>()); 144 } while(bytes_read == bufsize); 145 } 146 147 // receive answer 148 { 149 const sal_Int32 bufsize = 1024; 150 char buf[bufsize]; 151 sal_Int32 bytes_read = socket->read(buf, bufsize); 152 OString answer(buf, bytes_read); 153 const sal_Int32 returncode_start = answer.indexOf(' '); 154 if(returncode_start==-1 || !answer.copy(returncode_start, 4).equals(OString(" 200"))) 155 throw RuntimeException( 156 OUString::createFromAscii("SOAP server returns a error"), 157 Reference<XInterface>()); 158 } 159 } 160 } 161