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 25cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove 26cdf0e10cSrcweir #include "precompiled_extensions.hxx" 27cdf0e10cSrcweir 28cdf0e10cSrcweir #include "soaprequest.hxx" 29cdf0e10cSrcweir #include "errormail.hxx" 30cdf0e10cSrcweir #include "config.hxx" 31cdf0e10cSrcweir #include <boost/shared_ptr.hpp> 32cdf0e10cSrcweir #include <com/sun/star/lang/XMultiComponentFactory.hpp> 33cdf0e10cSrcweir #include <com/sun/star/lang/XMultiServiceFactory.hpp> 34cdf0e10cSrcweir #include <com/sun/star/ucb/XSimpleFileAccess.hpp> 35cdf0e10cSrcweir #include <rtl/strbuf.hxx> 36cdf0e10cSrcweir #include <rtl/ustring.hxx> 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::XOutputStream; 44cdf0e10cSrcweir using com::sun::star::ucb::XSimpleFileAccess; 45cdf0e10cSrcweir using rtl::OUString; 46cdf0e10cSrcweir using rtl::OString; 47cdf0e10cSrcweir using rtl::OStringBuffer; 48cdf0e10cSrcweir 49cdf0e10cSrcweir 50cdf0e10cSrcweir namespace 51cdf0e10cSrcweir { asUlong(sal_Int8 input)52cdf0e10cSrcweir static unsigned long asUlong(sal_Int8 input) 53cdf0e10cSrcweir { 54cdf0e10cSrcweir return *reinterpret_cast<unsigned char *>(&input); 55cdf0e10cSrcweir }; 56cdf0e10cSrcweir base64_encode(const Sequence<sal_Int8> & input)57cdf0e10cSrcweir static Sequence<sal_Int8> base64_encode(const Sequence<sal_Int8>& input) 58cdf0e10cSrcweir { 59cdf0e10cSrcweir static const char base64_tab[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; 60cdf0e10cSrcweir Sequence<sal_Int8> result(4); 61cdf0e10cSrcweir unsigned long value = asUlong(input[0]) << 16; 62cdf0e10cSrcweir if(input.getLength() > 1) value |= asUlong(input[1]) << 8; 63cdf0e10cSrcweir if(input.getLength() > 2) value |= asUlong(input[2]); 64cdf0e10cSrcweir 65cdf0e10cSrcweir result[0] = static_cast<sal_Int8>(base64_tab[(value >> 18) & 0x3F]); 66cdf0e10cSrcweir result[1] = static_cast<sal_Int8>(base64_tab[(value >> 12) & 0x3F]); 67cdf0e10cSrcweir result[2] = static_cast<sal_Int8>('='); 68cdf0e10cSrcweir result[3] = static_cast<sal_Int8>('='); 69cdf0e10cSrcweir 70cdf0e10cSrcweir if (input.getLength() > 1) 71cdf0e10cSrcweir { 72cdf0e10cSrcweir result[2] = base64_tab[(value >> 6) & 0x3F]; 73cdf0e10cSrcweir if (input.getLength() > 2) 74cdf0e10cSrcweir result[3] = base64_tab[(value >> 0) & 0x3F]; 75cdf0e10cSrcweir } 76cdf0e10cSrcweir return result; 77cdf0e10cSrcweir }; 78cdf0e10cSrcweir replaceAll(const OString & str,sal_Char old,const OString & replacement)79cdf0e10cSrcweir static OString replaceAll(const OString& str, sal_Char old, const OString& replacement) 80cdf0e10cSrcweir { 81cdf0e10cSrcweir OStringBuffer result; 82cdf0e10cSrcweir sal_Int32 idx = 0; 83cdf0e10cSrcweir do { 84cdf0e10cSrcweir result.append(str.getToken(0, old, idx)); 85cdf0e10cSrcweir if(idx>=0) result.append(replacement); 86cdf0e10cSrcweir } while(idx >= 0); 87cdf0e10cSrcweir return result.makeStringAndClear(); 88cdf0e10cSrcweir }; 89cdf0e10cSrcweir xmlEncode(const OString & input)90cdf0e10cSrcweir static OString xmlEncode(const OString& input) 91cdf0e10cSrcweir { 92cdf0e10cSrcweir OString result = replaceAll(input, '&', OString("&")); 93cdf0e10cSrcweir result = replaceAll(result, '<', OString("<")); 94cdf0e10cSrcweir return replaceAll(result, '>', OString(">")); 95cdf0e10cSrcweir } 96cdf0e10cSrcweir createSequenceFromString(const OString & str)97cdf0e10cSrcweir static shared_ptr<Sequence<sal_Int8> > createSequenceFromString(const OString& str) 98cdf0e10cSrcweir { 99cdf0e10cSrcweir const sal_Int32 size = str.getLength(); 100cdf0e10cSrcweir shared_ptr<Sequence<sal_Int8> > result(new Sequence<sal_Int8>(size)); 101cdf0e10cSrcweir for(sal_Int32 idx=0; idx < size; idx++) 102cdf0e10cSrcweir (*result)[idx] = str[idx]; 103cdf0e10cSrcweir return result; 104cdf0e10cSrcweir }; 105cdf0e10cSrcweir writeString(const Reference<XOutputStream> & target,const OString & str)106cdf0e10cSrcweir static void writeString(const Reference<XOutputStream>& target, const OString& str) 107cdf0e10cSrcweir { 108cdf0e10cSrcweir shared_ptr<Sequence<sal_Int8> > seq = createSequenceFromString(str); 109cdf0e10cSrcweir target->writeBytes(*seq); 110cdf0e10cSrcweir }; 111cdf0e10cSrcweir writeFile(const Reference<XMultiServiceFactory> & sf,const Reference<XOutputStream> & target,const OUString & fileurl)112cdf0e10cSrcweir static void writeFile(const Reference<XMultiServiceFactory>& sf, const Reference<XOutputStream>& target, const OUString& fileurl) 113cdf0e10cSrcweir { 114cdf0e10cSrcweir Reference<XSimpleFileAccess> file_access( 115cdf0e10cSrcweir sf->createInstance(OUString::createFromAscii("com.sun.star.ucb.SimpleFileAccess")), 116cdf0e10cSrcweir UNO_QUERY); 117cdf0e10cSrcweir Reference<XInputStream> file = file_access->openFileRead(fileurl); 118cdf0e10cSrcweir const sal_Int32 bufsize = 3; 119cdf0e10cSrcweir sal_Int32 bytes_read; 120cdf0e10cSrcweir Sequence<sal_Int8> buf(bufsize); 121cdf0e10cSrcweir do 122cdf0e10cSrcweir { 123cdf0e10cSrcweir bytes_read = file->readBytes(buf, bufsize); 124cdf0e10cSrcweir if(bytes_read < buf.getLength()) buf.realloc(bytes_read); 125cdf0e10cSrcweir if(bytes_read) target->writeBytes(base64_encode(buf)); 126cdf0e10cSrcweir } while(bytes_read == bufsize); 127cdf0e10cSrcweir }; 128cdf0e10cSrcweir 129cdf0e10cSrcweir static const OString SOAP_START( 130cdf0e10cSrcweir "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" 131cdf0e10cSrcweir "<SOAP-ENV:Envelope xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\"\n" 132cdf0e10cSrcweir "xmlns:SOAP-ENC=\"http://schemas.xmlsoap.org/soap/encoding/\"\n" 133cdf0e10cSrcweir "xmlns:xsi=\"http://www.w3.org/1999/XMLSchema-instance\"\n" 134cdf0e10cSrcweir "xmlns:xsd=\"http://www.w3.org/1999/XMLSchema\"\n" 135cdf0e10cSrcweir "xmlns:rds=\"urn:ReportDataService\"\n" 136cdf0e10cSrcweir "xmlns:apache=\"http://xml.apache.org/xml-soap\"\n" 137cdf0e10cSrcweir "SOAP-ENV:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\">\n" 138cdf0e10cSrcweir "<SOAP-ENV:Body>\n" 139cdf0e10cSrcweir "<rds:submitReport>\n"); 140cdf0e10cSrcweir static const OString SOAP_ITEMS_START("<hash xsi:type=\"apache:Map\">\n"); 141cdf0e10cSrcweir static const OString SOAP_ITEMS_END("</hash>\n"); 142cdf0e10cSrcweir static const OString SOAP_END( 143cdf0e10cSrcweir "</rds:submitReport>\n" 144cdf0e10cSrcweir "</SOAP-ENV:Body>\n" 145cdf0e10cSrcweir "</SOAP-ENV:Envelope>\n"); 146cdf0e10cSrcweir static const OString SOAP_ITEM_END("]]></value></item>\n"); 147cdf0e10cSrcweir getSoapOfficeversion(const Reference<XMultiServiceFactory> & sf)148cdf0e10cSrcweir static const OString getSoapOfficeversion(const Reference<XMultiServiceFactory>& sf) 149cdf0e10cSrcweir { 150cdf0e10cSrcweir return ::rtl::OUStringToOString(oooimprovement::Config(sf).getCompleteProductname(), RTL_TEXTENCODING_ASCII_US); 151cdf0e10cSrcweir }; 152cdf0e10cSrcweir getSoapSoapId(const Reference<XMultiServiceFactory> & sf,const OString & soap_id)153cdf0e10cSrcweir static const OString getSoapSoapId(const Reference<XMultiServiceFactory>& sf, const OString& soap_id) 154cdf0e10cSrcweir { 155cdf0e10cSrcweir OStringBuffer buf; 156cdf0e10cSrcweir buf.append("<body xsi:type=\"xsd:string\">"); 157cdf0e10cSrcweir buf.append(xmlEncode(soap_id)).append("\n"); 158cdf0e10cSrcweir buf.append(xmlEncode(getSoapOfficeversion(sf))).append("\n"); 159cdf0e10cSrcweir buf.append("</body>\n"); 160cdf0e10cSrcweir return buf.makeStringAndClear(); 161cdf0e10cSrcweir }; 162cdf0e10cSrcweir getSoapItemStart(const OString & key)163cdf0e10cSrcweir static const OString getSoapItemStart(const OString& key) 164cdf0e10cSrcweir { 165cdf0e10cSrcweir OStringBuffer buf = 166cdf0e10cSrcweir "<item>\n" 167cdf0e10cSrcweir "<key xsi:type=\"xsd:string\">" + key + "</key>\n" 168cdf0e10cSrcweir "<value xsi:type=\"xsd:string\"><![CDATA["; 169cdf0e10cSrcweir return buf.makeStringAndClear(); 170cdf0e10cSrcweir }; 171cdf0e10cSrcweir } 172cdf0e10cSrcweir 173cdf0e10cSrcweir namespace oooimprovement 174cdf0e10cSrcweir { SoapRequest(const Reference<XMultiServiceFactory> & sf,const OUString & soap_id,const OUString & logfile)175cdf0e10cSrcweir SoapRequest::SoapRequest(const Reference<XMultiServiceFactory>& sf, const OUString& soap_id, const OUString& logfile) 176cdf0e10cSrcweir : m_ServiceFactory(sf) 177cdf0e10cSrcweir , m_SoapId(soap_id) 178cdf0e10cSrcweir , m_Logfile(logfile) 179cdf0e10cSrcweir {} 180cdf0e10cSrcweir writeTo(const Reference<XOutputStream> & target) const181cdf0e10cSrcweir void SoapRequest::writeTo(const Reference<XOutputStream>& target) const 182cdf0e10cSrcweir { 183cdf0e10cSrcweir writeString(target, SOAP_START); 184cdf0e10cSrcweir writeString( 185cdf0e10cSrcweir target, 186cdf0e10cSrcweir getSoapSoapId(m_ServiceFactory, rtl::OUStringToOString(m_SoapId, RTL_TEXTENCODING_ASCII_US))); 187cdf0e10cSrcweir writeString(target, SOAP_ITEMS_START); 188cdf0e10cSrcweir writeString(target, getSoapItemStart("reportmail.xml")); 189cdf0e10cSrcweir writeString(target, Errormail(m_ServiceFactory).getXml()); 190cdf0e10cSrcweir writeString(target, SOAP_ITEM_END); 191cdf0e10cSrcweir writeString(target, getSoapItemStart("data.zip")); 192cdf0e10cSrcweir writeFile(m_ServiceFactory, target, m_Logfile); 193cdf0e10cSrcweir writeString(target, SOAP_ITEM_END); 194cdf0e10cSrcweir writeString(target, SOAP_ITEMS_END); 195cdf0e10cSrcweir writeString(target, SOAP_END); 196cdf0e10cSrcweir } 197cdf0e10cSrcweir } 198