1*cdf0e10cSrcweir /*************************************************************************
2*cdf0e10cSrcweir  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
3*cdf0e10cSrcweir  *
4*cdf0e10cSrcweir  * Copyright 2000, 2010 Oracle and/or its affiliates.
5*cdf0e10cSrcweir  *
6*cdf0e10cSrcweir  * OpenOffice.org - a multi-platform office productivity suite
7*cdf0e10cSrcweir  *
8*cdf0e10cSrcweir  * This file is part of OpenOffice.org.
9*cdf0e10cSrcweir  *
10*cdf0e10cSrcweir  * OpenOffice.org is free software: you can redistribute it and/or modify
11*cdf0e10cSrcweir  * it under the terms of the GNU Lesser General Public License version 3
12*cdf0e10cSrcweir  * only, as published by the Free Software Foundation.
13*cdf0e10cSrcweir  *
14*cdf0e10cSrcweir  * OpenOffice.org is distributed in the hope that it will be useful,
15*cdf0e10cSrcweir  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16*cdf0e10cSrcweir  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17*cdf0e10cSrcweir  * GNU Lesser General Public License version 3 for more details
18*cdf0e10cSrcweir  * (a copy is included in the LICENSE file that accompanied this code).
19*cdf0e10cSrcweir  *
20*cdf0e10cSrcweir  * You should have received a copy of the GNU Lesser General Public License
21*cdf0e10cSrcweir  * version 3 along with OpenOffice.org.  If not, see
22*cdf0e10cSrcweir  * <http://www.openoffice.org/license.html>
23*cdf0e10cSrcweir  * for a copy of the LGPLv3 License.
24*cdf0e10cSrcweir  *
25*cdf0e10cSrcweir  ************************************************************************/
26*cdf0e10cSrcweir 
27*cdf0e10cSrcweir 
28*cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
29*cdf0e10cSrcweir #include "precompiled_extensions.hxx"
30*cdf0e10cSrcweir 
31*cdf0e10cSrcweir #include "soaprequest.hxx"
32*cdf0e10cSrcweir #include "errormail.hxx"
33*cdf0e10cSrcweir #include "config.hxx"
34*cdf0e10cSrcweir #include <boost/shared_ptr.hpp>
35*cdf0e10cSrcweir #include <com/sun/star/lang/XMultiComponentFactory.hpp>
36*cdf0e10cSrcweir #include <com/sun/star/lang/XMultiServiceFactory.hpp>
37*cdf0e10cSrcweir #include <com/sun/star/ucb/XSimpleFileAccess.hpp>
38*cdf0e10cSrcweir #include <rtl/strbuf.hxx>
39*cdf0e10cSrcweir #include <rtl/ustring.hxx>
40*cdf0e10cSrcweir 
41*cdf0e10cSrcweir 
42*cdf0e10cSrcweir using namespace com::sun::star::uno;
43*cdf0e10cSrcweir using namespace com::sun::star::lang;
44*cdf0e10cSrcweir using namespace com::sun::star::io;
45*cdf0e10cSrcweir using boost::shared_ptr;
46*cdf0e10cSrcweir using com::sun::star::io::XOutputStream;
47*cdf0e10cSrcweir using com::sun::star::ucb::XSimpleFileAccess;
48*cdf0e10cSrcweir using rtl::OUString;
49*cdf0e10cSrcweir using rtl::OString;
50*cdf0e10cSrcweir using rtl::OStringBuffer;
51*cdf0e10cSrcweir 
52*cdf0e10cSrcweir 
53*cdf0e10cSrcweir namespace
54*cdf0e10cSrcweir {
55*cdf0e10cSrcweir     static unsigned long asUlong(sal_Int8 input)
56*cdf0e10cSrcweir     {
57*cdf0e10cSrcweir         return *reinterpret_cast<unsigned char *>(&input);
58*cdf0e10cSrcweir     };
59*cdf0e10cSrcweir 
60*cdf0e10cSrcweir     static Sequence<sal_Int8> base64_encode(const Sequence<sal_Int8>& input)
61*cdf0e10cSrcweir     {
62*cdf0e10cSrcweir         static const char base64_tab[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
63*cdf0e10cSrcweir         Sequence<sal_Int8> result(4);
64*cdf0e10cSrcweir         unsigned long value = asUlong(input[0]) << 16;
65*cdf0e10cSrcweir         if(input.getLength() > 1) value |= asUlong(input[1]) << 8;
66*cdf0e10cSrcweir         if(input.getLength() > 2) value |= asUlong(input[2]);
67*cdf0e10cSrcweir 
68*cdf0e10cSrcweir         result[0] = static_cast<sal_Int8>(base64_tab[(value >> 18) & 0x3F]);
69*cdf0e10cSrcweir         result[1] = static_cast<sal_Int8>(base64_tab[(value >> 12) & 0x3F]);
70*cdf0e10cSrcweir         result[2] = static_cast<sal_Int8>('=');
71*cdf0e10cSrcweir         result[3] = static_cast<sal_Int8>('=');
72*cdf0e10cSrcweir 
73*cdf0e10cSrcweir         if (input.getLength() > 1)
74*cdf0e10cSrcweir         {
75*cdf0e10cSrcweir             result[2] = base64_tab[(value >> 6) & 0x3F];
76*cdf0e10cSrcweir             if (input.getLength() > 2)
77*cdf0e10cSrcweir                  result[3] = base64_tab[(value >> 0) & 0x3F];
78*cdf0e10cSrcweir         }
79*cdf0e10cSrcweir         return result;
80*cdf0e10cSrcweir     };
81*cdf0e10cSrcweir 
82*cdf0e10cSrcweir     static OString replaceAll(const OString& str, sal_Char old, const OString& replacement)
83*cdf0e10cSrcweir     {
84*cdf0e10cSrcweir         OStringBuffer result;
85*cdf0e10cSrcweir         sal_Int32 idx = 0;
86*cdf0e10cSrcweir         do {
87*cdf0e10cSrcweir             result.append(str.getToken(0, old, idx));
88*cdf0e10cSrcweir             if(idx>=0) result.append(replacement);
89*cdf0e10cSrcweir         } while(idx >= 0);
90*cdf0e10cSrcweir         return result.makeStringAndClear();
91*cdf0e10cSrcweir     };
92*cdf0e10cSrcweir 
93*cdf0e10cSrcweir     static OString xmlEncode(const OString& input)
94*cdf0e10cSrcweir     {
95*cdf0e10cSrcweir         OString result = replaceAll(input, '&', OString("&amp;"));
96*cdf0e10cSrcweir         result = replaceAll(result, '<', OString("&lt;"));
97*cdf0e10cSrcweir         return replaceAll(result, '>', OString("&gt;"));
98*cdf0e10cSrcweir     }
99*cdf0e10cSrcweir 
100*cdf0e10cSrcweir     static shared_ptr<Sequence<sal_Int8> > createSequenceFromString(const OString& str)
101*cdf0e10cSrcweir     {
102*cdf0e10cSrcweir         const sal_Int32 size = str.getLength();
103*cdf0e10cSrcweir         shared_ptr<Sequence<sal_Int8> > result(new Sequence<sal_Int8>(size));
104*cdf0e10cSrcweir         for(sal_Int32 idx=0; idx < size; idx++)
105*cdf0e10cSrcweir             (*result)[idx] = str[idx];
106*cdf0e10cSrcweir         return result;
107*cdf0e10cSrcweir     };
108*cdf0e10cSrcweir 
109*cdf0e10cSrcweir     static void writeString(const Reference<XOutputStream>& target, const OString& str)
110*cdf0e10cSrcweir     {
111*cdf0e10cSrcweir         shared_ptr<Sequence<sal_Int8> > seq = createSequenceFromString(str);
112*cdf0e10cSrcweir         target->writeBytes(*seq);
113*cdf0e10cSrcweir     };
114*cdf0e10cSrcweir 
115*cdf0e10cSrcweir     static void writeFile(const Reference<XMultiServiceFactory>& sf, const Reference<XOutputStream>& target, const OUString& fileurl)
116*cdf0e10cSrcweir     {
117*cdf0e10cSrcweir         Reference<XSimpleFileAccess> file_access(
118*cdf0e10cSrcweir             sf->createInstance(OUString::createFromAscii("com.sun.star.ucb.SimpleFileAccess")),
119*cdf0e10cSrcweir             UNO_QUERY);
120*cdf0e10cSrcweir         Reference<XInputStream> file = file_access->openFileRead(fileurl);
121*cdf0e10cSrcweir         const sal_Int32 bufsize = 3;
122*cdf0e10cSrcweir         sal_Int32 bytes_read;
123*cdf0e10cSrcweir         Sequence<sal_Int8> buf(bufsize);
124*cdf0e10cSrcweir         do
125*cdf0e10cSrcweir         {
126*cdf0e10cSrcweir             bytes_read = file->readBytes(buf, bufsize);
127*cdf0e10cSrcweir             if(bytes_read < buf.getLength()) buf.realloc(bytes_read);
128*cdf0e10cSrcweir             if(bytes_read) target->writeBytes(base64_encode(buf));
129*cdf0e10cSrcweir         } while(bytes_read == bufsize);
130*cdf0e10cSrcweir     };
131*cdf0e10cSrcweir 
132*cdf0e10cSrcweir     static const OString SOAP_START(
133*cdf0e10cSrcweir         "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
134*cdf0e10cSrcweir         "<SOAP-ENV:Envelope xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\"\n"
135*cdf0e10cSrcweir         "xmlns:SOAP-ENC=\"http://schemas.xmlsoap.org/soap/encoding/\"\n"
136*cdf0e10cSrcweir         "xmlns:xsi=\"http://www.w3.org/1999/XMLSchema-instance\"\n"
137*cdf0e10cSrcweir         "xmlns:xsd=\"http://www.w3.org/1999/XMLSchema\"\n"
138*cdf0e10cSrcweir         "xmlns:rds=\"urn:ReportDataService\"\n"
139*cdf0e10cSrcweir         "xmlns:apache=\"http://xml.apache.org/xml-soap\"\n"
140*cdf0e10cSrcweir         "SOAP-ENV:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\">\n"
141*cdf0e10cSrcweir         "<SOAP-ENV:Body>\n"
142*cdf0e10cSrcweir         "<rds:submitReport>\n");
143*cdf0e10cSrcweir     static const OString SOAP_ITEMS_START("<hash xsi:type=\"apache:Map\">\n");
144*cdf0e10cSrcweir     static const OString SOAP_ITEMS_END("</hash>\n");
145*cdf0e10cSrcweir     static const OString SOAP_END(
146*cdf0e10cSrcweir         "</rds:submitReport>\n"
147*cdf0e10cSrcweir         "</SOAP-ENV:Body>\n"
148*cdf0e10cSrcweir         "</SOAP-ENV:Envelope>\n");
149*cdf0e10cSrcweir     static const OString SOAP_ITEM_END("]]></value></item>\n");
150*cdf0e10cSrcweir 
151*cdf0e10cSrcweir     static const OString getSoapOfficeversion(const Reference<XMultiServiceFactory>& sf)
152*cdf0e10cSrcweir     {
153*cdf0e10cSrcweir         return ::rtl::OUStringToOString(oooimprovement::Config(sf).getCompleteProductname(), RTL_TEXTENCODING_ASCII_US);
154*cdf0e10cSrcweir     };
155*cdf0e10cSrcweir 
156*cdf0e10cSrcweir     static const OString getSoapSoapId(const Reference<XMultiServiceFactory>& sf, const OString& soap_id)
157*cdf0e10cSrcweir     {
158*cdf0e10cSrcweir         OStringBuffer buf;
159*cdf0e10cSrcweir         buf.append("<body xsi:type=\"xsd:string\">");
160*cdf0e10cSrcweir         buf.append(xmlEncode(soap_id)).append("\n");
161*cdf0e10cSrcweir         buf.append(xmlEncode(getSoapOfficeversion(sf))).append("\n");
162*cdf0e10cSrcweir         buf.append("</body>\n");
163*cdf0e10cSrcweir         return buf.makeStringAndClear();
164*cdf0e10cSrcweir     };
165*cdf0e10cSrcweir 
166*cdf0e10cSrcweir     static const OString getSoapItemStart(const OString& key)
167*cdf0e10cSrcweir     {
168*cdf0e10cSrcweir         OStringBuffer buf =
169*cdf0e10cSrcweir             "<item>\n"
170*cdf0e10cSrcweir             "<key xsi:type=\"xsd:string\">" + key + "</key>\n"
171*cdf0e10cSrcweir             "<value xsi:type=\"xsd:string\"><![CDATA[";
172*cdf0e10cSrcweir         return buf.makeStringAndClear();
173*cdf0e10cSrcweir     };
174*cdf0e10cSrcweir }
175*cdf0e10cSrcweir 
176*cdf0e10cSrcweir namespace oooimprovement
177*cdf0e10cSrcweir {
178*cdf0e10cSrcweir     SoapRequest::SoapRequest(const Reference<XMultiServiceFactory>& sf, const OUString& soap_id, const OUString& logfile)
179*cdf0e10cSrcweir         : m_ServiceFactory(sf)
180*cdf0e10cSrcweir         , m_SoapId(soap_id)
181*cdf0e10cSrcweir         , m_Logfile(logfile)
182*cdf0e10cSrcweir     {}
183*cdf0e10cSrcweir 
184*cdf0e10cSrcweir      void SoapRequest::writeTo(const Reference<XOutputStream>& target) const
185*cdf0e10cSrcweir     {
186*cdf0e10cSrcweir         writeString(target, SOAP_START);
187*cdf0e10cSrcweir             writeString(
188*cdf0e10cSrcweir                 target,
189*cdf0e10cSrcweir                 getSoapSoapId(m_ServiceFactory, rtl::OUStringToOString(m_SoapId, RTL_TEXTENCODING_ASCII_US)));
190*cdf0e10cSrcweir             writeString(target, SOAP_ITEMS_START);
191*cdf0e10cSrcweir                 writeString(target, getSoapItemStart("reportmail.xml"));
192*cdf0e10cSrcweir                     writeString(target, Errormail(m_ServiceFactory).getXml());
193*cdf0e10cSrcweir                 writeString(target, SOAP_ITEM_END);
194*cdf0e10cSrcweir                 writeString(target, getSoapItemStart("data.zip"));
195*cdf0e10cSrcweir                     writeFile(m_ServiceFactory, target, m_Logfile);
196*cdf0e10cSrcweir                 writeString(target, SOAP_ITEM_END);
197*cdf0e10cSrcweir             writeString(target, SOAP_ITEMS_END);
198*cdf0e10cSrcweir         writeString(target, SOAP_END);
199*cdf0e10cSrcweir     }
200*cdf0e10cSrcweir }
201